final-orm
Version:
> Please check out https://github.com/oknoah/final and https://github.com/oknoah/final/packages/arangolize for similar projects that MAY be more up to date
313 lines (249 loc) • 8.2 kB
JavaScript
'use strict';
var _dotenv = require('dotenv');
var _dotenv2 = _interopRequireDefault(_dotenv);
var _crypto = require('crypto');
var _index = require('./index');
var _index2 = _interopRequireDefault(_index);
var _moment = require('moment');
var _moment2 = _interopRequireDefault(_moment);
var _lodash = require('lodash');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
_dotenv2.default.config();
const { TEST_EXTERNAL_HOST, ARANGO_PORT_8529_TCP_PROTO, ARANGO_USERNAME, ARANGO_PASSWORD, ARANGO_PORT_8529_TCP_ADDR, ARANGO_PORT_8529_TCP_PORT, ARANGO_DATABASE } = process.env;
const username = `test${(0, _crypto.randomBytes)(8).toString('hex')}`;
let db = _index2.default.connect({
database: ARANGO_DATABASE || 'test',
user: ARANGO_USERNAME,
password: ARANGO_PASSWORD,
host: ARANGO_PORT_8529_TCP_ADDR,
port: ARANGO_PORT_8529_TCP_PORT,
ARANGO_PORT_8529_TCP_PROTO: ARANGO_PORT_8529_TCP_PROTO,
url: `${ARANGO_PORT_8529_TCP_PROTO}://${ARANGO_USERNAME}:${ARANGO_PASSWORD}@${ARANGO_PORT_8529_TCP_ADDR}:${ARANGO_PORT_8529_TCP_PORT}`
});
class User extends db.Model {}
User.schema = {
name: { $type: String, index: true, unique: true },
email: { $type: String, index: true, unique: true },
profile: {
vegan: { $type: Boolean, optional: true }
}
};
class Post extends db.Model {}
Post.schema = {
body: { $type: String, optional: true },
creator: { $type: User, optional: false }
};
class Likes extends db.Edge {}
test('initialize ormjs', () => {
expect(db).toHaveProperty('Edge');
expect(db).toHaveProperty('Model');
});
test('create new user model instance', async () => {
const getEmail = () => `test${(0, _crypto.randomBytes)(2).toString('HEX')}@tinyrama.com`;
const newUser = await User.add({
name: username,
email: getEmail()
});
let newUsers = new Array(10);
newUsers.fill((await User.add({
name: `username-${(0, _crypto.randomBytes)(2).toString('HEX')}`,
email: getEmail()
})));
newUsers = await Promise.all(newUsers);
expect(newUsers[0]._id).toBeTruthy();
expect(newUser._id).toBeTruthy();
});
test('check name must be unique', async () => {
try {
await User.add({ name: username });
} catch (error) {
expect(error).not.toHaveProperty('_id');
}
});
test('create test post', async () => {
const user = await User.findOne({ where: { name: username } });
const post = await Post.add({ body: username, creator: user });
expect(post.body === username).toBeTruthy();
expect(post.body.length > 4).toBeTruthy();
});
test('create edge collection relationship', async () => {
const user = await User.findOne({ where: { name: username } });
const post = await Post.findOne({ where: { body: username } });
const like = await Likes.add(user, post);
expect(like._from).toBe(user._id);
});
test('find collections by example', async () => {
const user = await User.findOne({ where: { name: username } });
expect(user).toHaveProperty('_key');
});
test('find edge collections by example', async () => {
const user = await User.findOne({ where: { name: username } });
const edge = await Likes.findOne({ where: { _from: user._id } });
expect(edge._from).toBe(user._id);
});
test('find only certain attributes', async () => {
const user = await User.findOne({
where: { name: username },
attributes: ['_id', 'createdAt']
});
expect(user.name).toBe(undefined);
expect(user._id).not.toBe(undefined);
});
test('make sure all documents have createdAt field', async () => {
const user = await User.findOne({
where: { name: username }
});
expect(user).toHaveProperty('createdAt');
expect((0, _moment2.default)(user.createdAt).isValid()).toBe(true);
});
test('make sure all documents have updatedAt field', async () => {
const post = await Post.findOne({
body: username
});
post.body = 'Updated!';
await post.save();
expect(post).toHaveProperty('updatedAt');
expect((0, _moment2.default)(post.updatedAt).isValid()).toBe(true);
});
test('use aql query', async () => {
const { aql, _database } = await db.Model;
const cursor = await _database.query(aql`for u in User limit 10 return u`);
const users = await cursor.all();
expect(users.length).toBe(10);
});
test('check list is sorted', async () => {
const posts = await Post.find({
sort: 'createdAt asc',
limit: 100
});
const sorted = await (0, _lodash.sortBy)(posts, ['createdAt']);
expect((0, _lodash.isEqual)(posts, sorted)).toBe(true);
expect((0, _lodash.isEqual)(posts, sorted.reverse())).not.toBe(true);
});
test('find with include', async () => {
const posts = await Post.find({
include: {
model: User,
as: 'creator'
}
});
expect(posts[0]).toHaveProperty('creator');
expect(posts[0]).toHaveProperty('_key');
expect(posts[0]).toHaveProperty('body');
});
test('find and count include', async () => {
const included = await Post.findAndCount({
include: {
model: User,
as: 'creator'
}
});
const { data: posts, meta: { count } } = included;
expect(posts[0]).toHaveProperty('creator');
expect(posts[0]).toHaveProperty('_key');
expect(posts[0]).toHaveProperty('body');
expect(typeof count === 'number').toBeTruthy();
});
// test('remove item', async () => {
// const userToRemove = await User.findOne({
// where: { name: username }
// })
// await userToRemove.remove()
// const user = await User.findOne({
// where: { name: username }
// })
// expect(user).toBe(null)
// })
test('do not allow injection', async () => {
const users = await User.find({
where: { name: `123" || user._id == 'User/4627980' || user.name == "hi` },
limit: 100
});
expect((0, _lodash.isEmpty)(users)).toBe(true);
// expect(statuses.includes(true) !== true).toBe(true)
});
test('find by include where', async () => {
const post = await Post.findOne({
include: {
as: 'creator',
where: { name: username }
}
});
expect(post.creator.name).toBe(username);
});
test('complex query', async () => {
const posts = await Post.findAndCount({
limit: 5,
skip: 0,
sort: 'createdAt DESC',
attributes: ['creator', 'createdAt'],
include: {
as: 'creator',
where: { name: username }
}
});
expect(posts.data[0].creator.name).toBe(username);
});
test('query with $with', async () => {
const posts = await User.findAndCount({
$with: 'User',
where: { name: username }
});
expect(posts.data[0].name).toBe(username);
});
// test('connect without localhost', async () => {
// /*
// The purpose of this test is to be sure other hosts work. I use ngrok like so
//
// bash> ngrok http 127.0.0.1:8529
//
// ngrok will output a WAN address like `123abc.ngrok.io` which you should make TEST_EXTERNAL_HOST in your env.
//
// https://github.com/OKNoah/final-orm/issues/16
// */
// db = ormjs.connect({
// host: TEST_EXTERNAL_HOST,
// protocol: 'https',
// port: 443,
// user: 'root',
// password: '',
// database: NAME || 'test'
// })
//
// class User2 extends db.Model {
// static schema = {
// name: { $type: String, index: true, unique: true },
// profile: {
// vegan: { $type: Boolean, optional: true }
// }
// }
// }
//
// const newUserName = username + '123'
//
// await User2.add({ name: newUserName })
//
// const user = await User2.findOne({
// where: { name: newUserName }
// })
//
// expect(TEST_EXTERNAL_HOST).not.toBe(undefined)
// expect(user).toHaveProperty('createdAt')
// expect(moment(user.createdAt).isValid()).toBe(true)
// })
test('make a class that dont exist', async () => {
class User4 extends db.Model {}
User4.schema = {
name: { $type: String, index: true, unique: true },
profile: {
vegan: { $type: Boolean, optional: true }
}
};
const newUserName = username + '123';
await User4.add({ name: newUserName });
const user = await User4.findOne({
where: { name: newUserName }
});
expect(user).toHaveProperty('createdAt');
expect((0, _moment2.default)(user.createdAt).isValid()).toBe(true);
});