* 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
408 lines
14 KiB
JavaScript
408 lines
14 KiB
JavaScript
"use strict";
|
||
// These tests check the "create" / "update" functionality of the REST API.
|
||
var auth = require('../src/Auth');
|
||
var cache = require('../src/cache');
|
||
var Config = require('../src/Config');
|
||
var Parse = require('parse/node').Parse;
|
||
var rest = require('../src/rest');
|
||
var request = require('request');
|
||
|
||
var config = new Config('test');
|
||
let database = config.database;
|
||
|
||
describe('rest create', () => {
|
||
it_exclude_dbs(['postgres'])('handles _id', done => {
|
||
rest.create(config, auth.nobody(config), 'Foo', {})
|
||
.then(() => database.adapter.find('Foo', { fields: {} }, {}, {}))
|
||
.then(results => {
|
||
expect(results.length).toEqual(1);
|
||
var obj = results[0];
|
||
expect(typeof obj.objectId).toEqual('string');
|
||
expect(obj._id).toBeUndefined();
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles array, object, date', (done) => {
|
||
let now = new Date();
|
||
var obj = {
|
||
array: [1, 2, 3],
|
||
object: {foo: 'bar'},
|
||
date: Parse._encode(now),
|
||
};
|
||
rest.create(config, auth.nobody(config), 'MyClass', obj)
|
||
.then(() => database.adapter.find('MyClass', { fields: {
|
||
array: { type: 'Array' },
|
||
object: { type: 'Object' },
|
||
date: { type: 'Date' },
|
||
} }, {}, {}))
|
||
.then(results => {
|
||
expect(results.length).toEqual(1);
|
||
var mob = results[0];
|
||
expect(mob.array instanceof Array).toBe(true);
|
||
expect(typeof mob.object).toBe('object');
|
||
expect(mob.date.__type).toBe('Date');
|
||
expect(new Date(mob.date.iso).getTime()).toBe(now.getTime());
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles object and subdocument', done => {
|
||
let obj = { subdoc: {foo: 'bar', wu: 'tan'} };
|
||
rest.create(config, auth.nobody(config), 'MyClass', obj)
|
||
.then(() => database.adapter.find('MyClass', { fields: {} }, {}, {}))
|
||
.then(results => {
|
||
expect(results.length).toEqual(1);
|
||
let mob = results[0];
|
||
expect(typeof mob.subdoc).toBe('object');
|
||
expect(mob.subdoc.foo).toBe('bar');
|
||
expect(mob.subdoc.wu).toBe('tan');
|
||
expect(typeof mob.objectId).toEqual('string');
|
||
let obj = { 'subdoc.wu': 'clan' };
|
||
return rest.update(config, auth.nobody(config), 'MyClass', mob.objectId, obj)
|
||
})
|
||
.then(() => database.adapter.find('MyClass', { fields: {} }, {}, {}))
|
||
.then(results => {
|
||
expect(results.length).toEqual(1);
|
||
let mob = results[0];
|
||
expect(typeof mob.subdoc).toBe('object');
|
||
expect(mob.subdoc.foo).toBe('bar');
|
||
expect(mob.subdoc.wu).toBe('clan');
|
||
done();
|
||
})
|
||
.catch(error => {
|
||
console.log(error);
|
||
fail();
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles create on non-existent class when disabled client class creation', (done) => {
|
||
var customConfig = Object.assign({}, config, {allowClientClassCreation: false});
|
||
rest.create(customConfig, auth.nobody(customConfig), 'ClientClassCreation', {})
|
||
.then(() => {
|
||
fail('Should throw an error');
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toEqual(Parse.Error.OPERATION_FORBIDDEN);
|
||
expect(err.message).toEqual('This user is not allowed to access ' +
|
||
'non-existent class: ClientClassCreation');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles create on existent class when disabled client class creation', (done) => {
|
||
var customConfig = Object.assign({}, config, {allowClientClassCreation: false});
|
||
config.database.loadSchema()
|
||
.then(schema => schema.addClassIfNotExists('ClientClassCreation', {}))
|
||
.then(actualSchema => {
|
||
expect(actualSchema.className).toEqual('ClientClassCreation');
|
||
return rest.create(customConfig, auth.nobody(customConfig), 'ClientClassCreation', {});
|
||
})
|
||
.then(() => {
|
||
done();
|
||
}, err => {
|
||
fail('Should not throw error')
|
||
});
|
||
});
|
||
|
||
it('handles user signup', (done) => {
|
||
var user = {
|
||
username: 'asdf',
|
||
password: 'zxcv',
|
||
foo: 'bar',
|
||
};
|
||
rest.create(config, auth.nobody(config), '_User', user)
|
||
.then((r) => {
|
||
expect(Object.keys(r.response).length).toEqual(3);
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles anonymous user signup', (done) => {
|
||
var data1 = {
|
||
authData: {
|
||
anonymous: {
|
||
id: '00000000-0000-0000-0000-000000000001'
|
||
}
|
||
}
|
||
};
|
||
var data2 = {
|
||
authData: {
|
||
anonymous: {
|
||
id: '00000000-0000-0000-0000-000000000002'
|
||
}
|
||
}
|
||
};
|
||
var username1;
|
||
rest.create(config, auth.nobody(config), '_User', data1)
|
||
.then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
return rest.create(config, auth.nobody(config), '_User', data1);
|
||
}).then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.username).toEqual('string');
|
||
expect(typeof r.response.updatedAt).toEqual('string');
|
||
username1 = r.response.username;
|
||
return rest.create(config, auth.nobody(config), '_User', data2);
|
||
}).then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
return rest.create(config, auth.nobody(config), '_User', data2);
|
||
}).then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.username).toEqual('string');
|
||
expect(typeof r.response.updatedAt).toEqual('string');
|
||
expect(r.response.username).not.toEqual(username1);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('handles anonymous user signup and upgrade to new user', (done) => {
|
||
var data1 = {
|
||
authData: {
|
||
anonymous: {
|
||
id: '00000000-0000-0000-0000-000000000001'
|
||
}
|
||
}
|
||
};
|
||
|
||
var updatedData = {
|
||
authData: { anonymous: null },
|
||
username: 'hello',
|
||
password: 'world'
|
||
}
|
||
var username1;
|
||
var objectId;
|
||
rest.create(config, auth.nobody(config), '_User', data1)
|
||
.then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
objectId = r.response.objectId;
|
||
return auth.getAuthForSessionToken({config, sessionToken: r.response.sessionToken })
|
||
}).then((sessionAuth) => {
|
||
return rest.update(config, sessionAuth, '_User', objectId, updatedData);
|
||
}).then((r) => {
|
||
return Parse.User.logOut().then(() => {
|
||
return Parse.User.logIn('hello', 'world');
|
||
})
|
||
}).then((r) => {
|
||
expect(r.id).toEqual(objectId);
|
||
expect(r.get('username')).toEqual('hello');
|
||
done();
|
||
}).catch((err) => {
|
||
fail('should not fail')
|
||
done();
|
||
})
|
||
});
|
||
|
||
it('handles no anonymous users config', (done) => {
|
||
var NoAnnonConfig = Object.assign({}, config);
|
||
NoAnnonConfig.authDataManager.setEnableAnonymousUsers(false);
|
||
var data1 = {
|
||
authData: {
|
||
anonymous: {
|
||
id: '00000000-0000-0000-0000-000000000001'
|
||
}
|
||
}
|
||
};
|
||
rest.create(NoAnnonConfig, auth.nobody(NoAnnonConfig), '_User', data1).then(() => {
|
||
fail("Should throw an error");
|
||
done();
|
||
}, (err) => {
|
||
expect(err.code).toEqual(Parse.Error.UNSUPPORTED_SERVICE);
|
||
expect(err.message).toEqual('This authentication method is unsupported.');
|
||
NoAnnonConfig.authDataManager.setEnableAnonymousUsers(true);
|
||
done();
|
||
})
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('test facebook signup and login', (done) => {
|
||
var data = {
|
||
authData: {
|
||
facebook: {
|
||
id: '8675309',
|
||
access_token: 'jenny'
|
||
}
|
||
}
|
||
};
|
||
var newUserSignedUpByFacebookObjectId;
|
||
rest.create(config, auth.nobody(config), '_User', data)
|
||
.then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
newUserSignedUpByFacebookObjectId = r.response.objectId;
|
||
return rest.create(config, auth.nobody(config), '_User', data);
|
||
}).then((r) => {
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.username).toEqual('string');
|
||
expect(typeof r.response.updatedAt).toEqual('string');
|
||
expect(r.response.objectId).toEqual(newUserSignedUpByFacebookObjectId);
|
||
return rest.find(config, auth.master(config),
|
||
'_Session', {sessionToken: r.response.sessionToken});
|
||
}).then((response) => {
|
||
expect(response.results.length).toEqual(1);
|
||
var output = response.results[0];
|
||
expect(output.user.objectId).toEqual(newUserSignedUpByFacebookObjectId);
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])('stores pointers', done => {
|
||
let obj = {
|
||
foo: 'bar',
|
||
aPointer: {
|
||
__type: 'Pointer',
|
||
className: 'JustThePointer',
|
||
objectId: 'qwerty'
|
||
}
|
||
};
|
||
rest.create(config, auth.nobody(config), 'APointerDarkly', obj)
|
||
.then(() => database.adapter.find('APointerDarkly', { fields: {
|
||
foo: { type: 'String' },
|
||
aPointer: { type: 'Pointer', targetClass: 'JustThePointer' },
|
||
}}, {}, {}))
|
||
.then(results => {
|
||
expect(results.length).toEqual(1);
|
||
let output = results[0];
|
||
expect(typeof output.foo).toEqual('string');
|
||
expect(typeof output._p_aPointer).toEqual('undefined');
|
||
expect(output._p_aPointer).toBeUndefined();
|
||
expect(output.aPointer).toEqual({
|
||
__type: 'Pointer',
|
||
className: 'JustThePointer',
|
||
objectId: 'qwerty'
|
||
});
|
||
done();
|
||
});
|
||
});
|
||
|
||
it("cannot set objectId", (done) => {
|
||
var headers = {
|
||
'Content-Type': 'application/octet-stream',
|
||
'X-Parse-Application-Id': 'test',
|
||
'X-Parse-REST-API-Key': 'rest'
|
||
};
|
||
request.post({
|
||
headers: headers,
|
||
url: 'http://localhost:8378/1/classes/TestObject',
|
||
body: JSON.stringify({
|
||
'foo': 'bar',
|
||
'objectId': 'hello'
|
||
})
|
||
}, (error, response, body) => {
|
||
var b = JSON.parse(body);
|
||
expect(b.code).toEqual(105);
|
||
expect(b.error).toEqual('objectId is an invalid field name.');
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])("test default session length", (done) => {
|
||
var user = {
|
||
username: 'asdf',
|
||
password: 'zxcv',
|
||
foo: 'bar',
|
||
};
|
||
var now = new Date();
|
||
|
||
rest.create(config, auth.nobody(config), '_User', user)
|
||
.then((r) => {
|
||
expect(Object.keys(r.response).length).toEqual(3);
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
return rest.find(config, auth.master(config),
|
||
'_Session', {sessionToken: r.response.sessionToken});
|
||
})
|
||
.then((r) => {
|
||
expect(r.results.length).toEqual(1);
|
||
|
||
var session = r.results[0];
|
||
var actual = new Date(session.expiresAt.iso);
|
||
var expected = new Date(now.getTime() + (1000 * 3600 * 24 * 365));
|
||
|
||
expect(actual.getFullYear()).toEqual(expected.getFullYear());
|
||
expect(actual.getMonth()).toEqual(expected.getMonth());
|
||
expect(actual.getDate()).toEqual(expected.getDate());
|
||
expect(actual.getMinutes()).toEqual(expected.getMinutes());
|
||
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])("test specified session length", (done) => {
|
||
var user = {
|
||
username: 'asdf',
|
||
password: 'zxcv',
|
||
foo: 'bar',
|
||
};
|
||
var sessionLength = 3600, // 1 Hour ahead
|
||
now = new Date(); // For reference later
|
||
config.sessionLength = sessionLength;
|
||
|
||
rest.create(config, auth.nobody(config), '_User', user)
|
||
.then((r) => {
|
||
expect(Object.keys(r.response).length).toEqual(3);
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
return rest.find(config, auth.master(config),
|
||
'_Session', {sessionToken: r.response.sessionToken});
|
||
})
|
||
.then((r) => {
|
||
expect(r.results.length).toEqual(1);
|
||
|
||
var session = r.results[0];
|
||
var actual = new Date(session.expiresAt.iso);
|
||
var expected = new Date(now.getTime() + (sessionLength*1000));
|
||
|
||
expect(actual.getFullYear()).toEqual(expected.getFullYear());
|
||
expect(actual.getMonth()).toEqual(expected.getMonth());
|
||
expect(actual.getDate()).toEqual(expected.getDate());
|
||
expect(actual.getHours()).toEqual(expected.getHours());
|
||
expect(actual.getMinutes()).toEqual(expected.getMinutes());
|
||
|
||
done();
|
||
});
|
||
});
|
||
|
||
it_exclude_dbs(['postgres'])("can create a session with no expiration", (done) => {
|
||
var user = {
|
||
username: 'asdf',
|
||
password: 'zxcv',
|
||
foo: 'bar'
|
||
};
|
||
config.expireInactiveSessions = false;
|
||
|
||
rest.create(config, auth.nobody(config), '_User', user)
|
||
.then((r) => {
|
||
expect(Object.keys(r.response).length).toEqual(3);
|
||
expect(typeof r.response.objectId).toEqual('string');
|
||
expect(typeof r.response.createdAt).toEqual('string');
|
||
expect(typeof r.response.sessionToken).toEqual('string');
|
||
return rest.find(config, auth.master(config),
|
||
'_Session', {sessionToken: r.response.sessionToken});
|
||
})
|
||
.then((r) => {
|
||
expect(r.results.length).toEqual(1);
|
||
|
||
var session = r.results[0];
|
||
expect(session.expiresAt).toBeUndefined();
|
||
|
||
done();
|
||
});
|
||
});
|
||
});
|