123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954 |
- 'use strict';
- const chai = require('chai');
- const expect = chai.expect;
- const Support = require('../../support');
- const dialect = Support.getTestDialect();
- const { DataTypes, Op } = require('@sequelize/core');
- describe('[POSTGRES Specific] DAO', () => {
- if (dialect !== 'postgres') {
- return;
- }
- beforeEach(async function () {
- this.User = this.sequelize.define('User', {
- username: DataTypes.STRING,
- email: { type: DataTypes.ARRAY(DataTypes.TEXT) },
- settings: DataTypes.HSTORE,
- document: { type: DataTypes.HSTORE, defaultValue: { default: "'value'" } },
- phones: DataTypes.ARRAY(DataTypes.HSTORE),
- friends: {
- type: DataTypes.ARRAY(DataTypes.JSON),
- defaultValue: [],
- },
- magic_numbers: {
- type: DataTypes.ARRAY(DataTypes.INTEGER),
- defaultValue: [],
- },
- course_period: DataTypes.RANGE(DataTypes.DATE),
- acceptable_marks: { type: DataTypes.RANGE(DataTypes.DECIMAL), defaultValue: [0.65, 1] },
- available_amount: DataTypes.RANGE,
- holidays: DataTypes.ARRAY(DataTypes.RANGE(DataTypes.DATE)),
- location: DataTypes.GEOMETRY(),
- });
- await this.User.sync({ force: true });
- });
- it('should be able to search within an array', async function () {
- await this.User.findAll({
- where: {
- email: ['hello', 'world'],
- },
- attributes: ['id', 'username', 'email', 'settings', 'document', 'phones', 'friends'],
- logging(sql) {
- expect(sql).to.equal(
- 'Executing (default): SELECT "id", "username", "email", "settings", "document", "phones", "friends" FROM "Users" AS "User" WHERE "User"."email" = ARRAY[\'hello\',\'world\'];',
- );
- },
- });
- });
- it('should be able to update a field with type ARRAY(JSON)', async function () {
- const userInstance = await this.User.create({
- username: 'bob',
- email: ['myemail@email.com'],
- friends: [
- {
- name: 'John Smith',
- },
- ],
- });
- expect(userInstance.friends).to.have.length(1);
- expect(userInstance.friends[0].name).to.equal('John Smith');
- const obj = await userInstance.update({
- friends: [
- {
- name: 'John Smythe',
- },
- ],
- });
- const friends = obj.friends;
- expect(friends).to.have.length(1);
- expect(friends[0].name).to.equal('John Smythe');
- });
- it('should be able to find a record while searching in an array', async function () {
- await this.User.bulkCreate([
- { username: 'bob', email: ['myemail@email.com'] },
- { username: 'tony', email: ['wrongemail@email.com'] },
- ]);
- const user = await this.User.findAll({ where: { email: ['myemail@email.com'] } });
- expect(user).to.be.instanceof(Array);
- expect(user).to.have.length(1);
- expect(user[0].username).to.equal('bob');
- });
- describe('hstore', () => {
- it('should tell me that a column is hstore and not USER-DEFINED', async function () {
- const table = await this.sequelize.queryInterface.describeTable('Users');
- expect(table.settings.type).to.equal('HSTORE');
- expect(table.document.type).to.equal('HSTORE');
- });
- // TODO: move to select QueryGenerator unit tests
- it('should NOT stringify hstore with insert', async function () {
- await this.User.create(
- {
- username: 'bob',
- email: ['myemail@email.com'],
- settings: { mailing: 'false', push: 'facebook', frequency: '3' },
- },
- {
- logging(sql) {
- const unexpected =
- '\'"mailing"=>"false","push"=>"facebook","frequency"=>"3"\',\'"default"=>"\'\'value\'\'"\'';
- expect(sql).not.to.include(unexpected);
- },
- },
- );
- });
- // TODO: move to select QueryGenerator unit tests
- it('should not rename hstore fields', async function () {
- const Equipment = this.sequelize.define('Equipment', {
- grapplingHook: {
- type: DataTypes.STRING,
- field: 'grappling_hook',
- },
- utilityBelt: {
- type: DataTypes.HSTORE,
- },
- });
- await Equipment.sync({ force: true });
- await Equipment.findAll({
- where: {
- utilityBelt: {
- grapplingHook: 'true',
- },
- },
- logging(sql) {
- expect(sql).to.contains(
- ' WHERE "Equipment"."utilityBelt" = \'"grapplingHook"=>"true"\';',
- );
- },
- });
- });
- });
- describe('range', () => {
- it('should tell me that a column is range and not USER-DEFINED', async function () {
- const table = await this.sequelize.queryInterface.describeTable('Users');
- expect(table.course_period.type).to.equal('TSTZRANGE');
- expect(table.available_amount.type).to.equal('INT4RANGE');
- });
- });
- describe('enums', () => {
- it('should be able to create enums with escape values', async function () {
- const User = this.sequelize.define('UserEnums', {
- mood: DataTypes.ENUM('happy', 'sad', "1970's"),
- });
- await User.sync({ force: true });
- });
- it('should be able to ignore enum types that already exist', async function () {
- const User = this.sequelize.define('UserEnums', {
- mood: DataTypes.ENUM('happy', 'sad', 'meh'),
- });
- await User.sync({ force: true });
- await User.sync();
- });
- it('should be able to create/drop enums multiple times', async function () {
- const User = this.sequelize.define('UserEnums', {
- mood: DataTypes.ENUM('happy', 'sad', 'meh'),
- });
- await User.sync({ force: true });
- await User.sync({ force: true });
- });
- it('should be able to create/drop multiple enums multiple times', async function () {
- const DummyModel = this.sequelize.define('Dummy-pg', {
- username: DataTypes.STRING,
- theEnumOne: {
- type: DataTypes.ENUM(['one', 'two', 'three']),
- },
- theEnumTwo: {
- type: DataTypes.ENUM(['four', 'five', 'six']),
- },
- });
- await DummyModel.sync({ force: true });
- // now sync one more time:
- await DummyModel.sync({ force: true });
- // sync without dropping
- await DummyModel.sync();
- });
- it('should be able to create/drop multiple enums multiple times with field name (#7812)', async function () {
- const DummyModel = this.sequelize.define('Dummy-pg', {
- username: DataTypes.STRING,
- theEnumOne: {
- field: 'oh_my_this_enum_one',
- type: DataTypes.ENUM(['one', 'two', 'three']),
- },
- theEnumTwo: {
- field: 'oh_my_this_enum_two',
- type: DataTypes.ENUM(['four', 'five', 'six']),
- },
- });
- await DummyModel.sync({ force: true });
- // now sync one more time:
- await DummyModel.sync({ force: true });
- // sync without dropping
- await DummyModel.sync();
- });
- it('should be able to add values to enum types', async function () {
- let User = this.sequelize.define('UserEnums', {
- mood: DataTypes.ENUM('happy', 'sad', 'meh'),
- });
- await User.sync({ force: true });
- User = this.sequelize.define('UserEnums', {
- mood: DataTypes.ENUM('neutral', 'happy', 'sad', 'ecstatic', 'meh', 'joyful'),
- });
- await User.sync();
- const enums = await this.sequelize.queryInterface.pgListEnums(User.table);
- expect(enums).to.have.length(1);
- expect(enums[0].enum_value).to.deep.equal([
- 'neutral',
- 'happy',
- 'sad',
- 'ecstatic',
- 'meh',
- 'joyful',
- ]);
- });
- it('should be able to add multiple values with different order', async function () {
- let User = this.sequelize.define('UserEnums', {
- priority: DataTypes.ENUM('1', '2', '6'),
- });
- await User.sync({ force: true });
- User = this.sequelize.define('UserEnums', {
- priority: DataTypes.ENUM('0', '1', '2', '3', '4', '5', '6', '7'),
- });
- await User.sync();
- const enums = await this.sequelize.queryInterface.pgListEnums(User.table);
- expect(enums).to.have.length(1);
- expect(enums[0].enum_value).to.deep.equal(['0', '1', '2', '3', '4', '5', '6', '7']);
- });
- describe('ARRAY(ENUM)', () => {
- it('should be able to ignore enum types that already exist', async function () {
- const User = this.sequelize.define('UserEnums', {
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- await User.sync();
- });
- it('should be able to create/drop enums multiple times', async function () {
- const User = this.sequelize.define('UserEnums', {
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- await User.sync({ force: true });
- });
- it('should be able to add values to enum types', async function () {
- let User = this.sequelize.define('UserEnums', {
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- User = this.sequelize.define('UserEnums', {
- permissions: DataTypes.ARRAY(
- DataTypes.ENUM('view', 'access', 'edit', 'write', 'check', 'delete'),
- ),
- });
- await User.sync();
- const enums = await this.sequelize.queryInterface.pgListEnums(User.table);
- expect(enums).to.have.length(1);
- expect(enums[0].enum_value).to.deep.equal([
- 'view',
- 'access',
- 'edit',
- 'write',
- 'check',
- 'delete',
- ]);
- });
- it('should be able to insert new record', async function () {
- const User = this.sequelize.define('UserEnums', {
- name: DataTypes.STRING,
- type: DataTypes.ENUM('A', 'B', 'C'),
- owners: DataTypes.ARRAY(DataTypes.STRING),
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- const user = await User.create({
- name: 'file.exe',
- type: 'C',
- owners: ['userA', 'userB'],
- permissions: ['access', 'write'],
- });
- expect(user.name).to.equal('file.exe');
- expect(user.type).to.equal('C');
- expect(user.owners).to.deep.equal(['userA', 'userB']);
- expect(user.permissions).to.deep.equal(['access', 'write']);
- });
- it('should be able to insert a new record even with a redefined field name', async function () {
- const User = this.sequelize.define('UserEnums', {
- name: DataTypes.STRING,
- type: DataTypes.ENUM('A', 'B', 'C'),
- owners: DataTypes.ARRAY(DataTypes.STRING),
- specialPermissions: {
- type: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- field: 'special_permissions',
- },
- });
- await User.sync({ force: true });
- const user = await User.bulkCreate([
- {
- name: 'file.exe',
- type: 'C',
- owners: ['userA', 'userB'],
- specialPermissions: ['access', 'write'],
- },
- ]);
- expect(user.length).to.equal(1);
- });
- it('should be able to insert a new record with an array of enums in a schema', async function () {
- const schema = 'special_schema';
- await this.sequelize.createSchema(schema);
- const User = this.sequelize.define(
- 'UserEnums',
- {
- name: DataTypes.STRING,
- type: DataTypes.ENUM('A', 'B', 'C'),
- owners: DataTypes.ARRAY(DataTypes.STRING),
- specialPermissions: {
- type: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- field: 'special_permissions',
- },
- },
- {
- schema,
- },
- );
- await User.sync({ force: true });
- const user = await User.bulkCreate([
- {
- name: 'file.exe',
- type: 'C',
- owners: ['userA', 'userB'],
- specialPermissions: ['access', 'write'],
- },
- ]);
- expect(user.length).to.equal(1);
- });
- it('should fail when trying to insert foreign element on ARRAY(ENUM)', async function () {
- const User = this.sequelize.define('UserEnums', {
- name: DataTypes.STRING,
- type: DataTypes.ENUM('A', 'B', 'C'),
- owners: DataTypes.ARRAY(DataTypes.STRING),
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- await expect(
- User.create({
- name: 'file.exe',
- type: 'C',
- owners: ['userA', 'userB'],
- permissions: ['cosmic_ray_disk_access'],
- }),
- ).to.be.rejectedWith(
- `'cosmic_ray_disk_access' is not a valid choice for enum [ 'access', 'write', 'check', 'delete' ]`,
- );
- });
- it('should be able to find records', async function () {
- const User = this.sequelize.define('UserEnums', {
- name: DataTypes.STRING,
- type: DataTypes.ENUM('A', 'B', 'C'),
- permissions: DataTypes.ARRAY(DataTypes.ENUM(['access', 'write', 'check', 'delete'])),
- });
- await User.sync({ force: true });
- await User.bulkCreate([
- {
- name: 'file1.exe',
- type: 'C',
- permissions: ['access', 'write'],
- },
- {
- name: 'file2.exe',
- type: 'A',
- permissions: ['access', 'check'],
- },
- {
- name: 'file3.exe',
- type: 'B',
- permissions: ['access', 'write', 'delete'],
- },
- ]);
- const users = await User.findAll({
- where: {
- type: {
- [Op.in]: ['A', 'C'],
- },
- permissions: {
- [Op.contains]: ['write'],
- },
- },
- });
- expect(users.length).to.equal(1);
- expect(users[0].name).to.equal('file1.exe');
- expect(users[0].type).to.equal('C');
- expect(users[0].permissions).to.deep.equal(['access', 'write']);
- });
- });
- });
- describe('integers', () => {
- describe('integer', () => {
- beforeEach(async function () {
- this.User = this.sequelize.define('User', {
- aNumber: DataTypes.INTEGER,
- });
- await this.User.sync({ force: true });
- });
- it('positive', async function () {
- const User = this.User;
- const user = await User.create({ aNumber: 2_147_483_647 });
- expect(user.aNumber).to.equal(2_147_483_647);
- const _user = await User.findOne({ where: { aNumber: 2_147_483_647 } });
- expect(_user.aNumber).to.equal(2_147_483_647);
- });
- it('negative', async function () {
- const User = this.User;
- const user = await User.create({ aNumber: -2_147_483_647 });
- expect(user.aNumber).to.equal(-2_147_483_647);
- const _user = await User.findOne({ where: { aNumber: -2_147_483_647 } });
- expect(_user.aNumber).to.equal(-2_147_483_647);
- });
- });
- describe('bigint', () => {
- beforeEach(async function () {
- this.User = this.sequelize.define('User', {
- aNumber: DataTypes.BIGINT,
- });
- await this.User.sync({ force: true });
- });
- it('positive', async function () {
- const User = this.User;
- const user = await User.create({ aNumber: '9223372036854775807' });
- expect(user.aNumber).to.equal('9223372036854775807');
- const _user = await User.findOne({ where: { aNumber: '9223372036854775807' } });
- expect(_user.aNumber).to.equal('9223372036854775807');
- });
- it('negative', async function () {
- const User = this.User;
- const user = await User.create({ aNumber: '-9223372036854775807' });
- expect(user.aNumber).to.equal('-9223372036854775807');
- const _user = await User.findOne({ where: { aNumber: '-9223372036854775807' } });
- expect(_user.aNumber).to.equal('-9223372036854775807');
- });
- });
- });
- describe('timestamps', () => {
- beforeEach(async function () {
- this.User = this.sequelize.define('User', {
- dates: DataTypes.ARRAY(DataTypes.DATE),
- });
- await this.User.sync({ force: true });
- });
- it('should use bind params instead of "TIMESTAMP WITH TIME ZONE"', async function () {
- await this.User.create(
- {
- dates: [],
- },
- {
- logging(sql) {
- expect(sql).not.to.contain('TIMESTAMP WITH TIME ZONE');
- expect(sql).not.to.contain('DATETIME');
- },
- },
- );
- });
- });
- describe('model', () => {
- it('create handles array correctly', async function () {
- const oldUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com', 'bar@baz.com'],
- });
- expect(oldUser.email).to.contain.members(['foo@bar.com', 'bar@baz.com']);
- });
- it('should save hstore correctly', async function () {
- const newUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com'],
- settings: { created: '"value"' },
- });
- // Check to see if the default value for an hstore field works
- expect(newUser.document).to.deep.equal({ default: "'value'" });
- expect(newUser.settings).to.deep.equal({ created: '"value"' });
- // Check to see if updating an hstore field works
- const oldUser = await newUser.update({
- settings: { should: 'update', to: 'this', first: 'place' },
- });
- // Postgres always returns keys in alphabetical order (ascending)
- expect(oldUser.settings).to.deep.equal({ first: 'place', should: 'update', to: 'this' });
- });
- it('should save hstore array correctly', async function () {
- const User = this.User;
- await this.User.create({
- username: 'bob',
- email: ['myemail@email.com'],
- phones: [
- { number: '123456789', type: 'mobile' },
- { number: '987654321', type: 'landline' },
- { number: '8675309', type: "Jenny's" },
- { number: '5555554321', type: '"home\n"' },
- ],
- });
- const user = await User.findByPk(1);
- expect(user.phones.length).to.equal(4);
- expect(user.phones[1].number).to.equal('987654321');
- expect(user.phones[2].type).to.equal("Jenny's");
- expect(user.phones[3].type).to.equal('"home\n"');
- });
- it('should bulkCreate with hstore property', async function () {
- const User = this.User;
- await this.User.bulkCreate([
- {
- username: 'bob',
- email: ['myemail@email.com'],
- settings: { mailing: 'true', push: 'facebook', frequency: '3' },
- },
- ]);
- const user = await User.findByPk(1);
- expect(user.settings.mailing).to.equal('true');
- });
- it('should update hstore correctly', async function () {
- const newUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com'],
- settings: { test: '"value"' },
- });
- // Check to see if the default value for an hstore field works
- expect(newUser.document).to.deep.equal({ default: "'value'" });
- expect(newUser.settings).to.deep.equal({ test: '"value"' });
- // Check to see if updating an hstore field works
- await this.User.update(
- { settings: { should: 'update', to: 'this', first: 'place' } },
- { where: newUser.where() },
- );
- await newUser.reload();
- // Postgres always returns keys in alphabetical order (ascending)
- expect(newUser.settings).to.deep.equal({ first: 'place', should: 'update', to: 'this' });
- });
- it('should update hstore correctly and return the affected rows', async function () {
- const oldUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com'],
- settings: { test: '"value"' },
- });
- // Update the user and check that the returned object's fields have been parsed by the hstore library
- const [count, users] = await this.User.update(
- { settings: { should: 'update', to: 'this', first: 'place' } },
- { where: oldUser.where(), returning: true },
- );
- expect(count).to.equal(1);
- expect(users[0].settings).to.deep.equal({ should: 'update', to: 'this', first: 'place' });
- });
- it('should read hstore correctly', async function () {
- const data = { username: 'user', email: ['foo@bar.com'], settings: { test: '"value"' } };
- await this.User.create(data);
- const user = await this.User.findOne({ where: { username: 'user' } });
- // Check that the hstore fields are the same when retrieving the user
- expect(user.settings).to.deep.equal(data.settings);
- });
- it('should read an hstore array correctly', async function () {
- const data = {
- username: 'user',
- email: ['foo@bar.com'],
- phones: [
- { number: '123456789', type: 'mobile' },
- { number: '987654321', type: 'landline' },
- ],
- };
- await this.User.create(data);
- // Check that the hstore fields are the same when retrieving the user
- const user = await this.User.findOne({ where: { username: 'user' } });
- expect(user.phones).to.deep.equal(data.phones);
- });
- it('should read hstore correctly from multiple rows', async function () {
- await this.User.create({
- username: 'user1',
- email: ['foo@bar.com'],
- settings: { test: '"value"' },
- });
- await this.User.create({
- username: 'user2',
- email: ['foo2@bar.com'],
- settings: { another: '"example"' },
- });
- // Check that the hstore fields are the same when retrieving the user
- const users = await this.User.findAll({ order: ['username'] });
- expect(users[0].settings).to.deep.equal({ test: '"value"' });
- expect(users[1].settings).to.deep.equal({ another: '"example"' });
- });
- it('should read hstore correctly from included models as well', async function () {
- const HstoreSubmodel = this.sequelize.define('hstoreSubmodel', {
- someValue: DataTypes.HSTORE,
- });
- const submodelValue = { testing: '"hstore"' };
- this.User.hasMany(HstoreSubmodel);
- await this.sequelize.sync({ force: true });
- const user0 = await this.User.create({ username: 'user1' });
- const submodel = await HstoreSubmodel.create({ someValue: submodelValue });
- await user0.setHstoreSubmodels([submodel]);
- const user = await this.User.findOne({
- where: { username: 'user1' },
- include: [HstoreSubmodel],
- });
- expect(user.hasOwnProperty('hstoreSubmodels')).to.be.ok;
- expect(user.hstoreSubmodels.length).to.equal(1);
- expect(user.hstoreSubmodels[0].someValue).to.deep.equal(submodelValue);
- });
- it('should save range correctly', async function () {
- const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];
- const newUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com'],
- course_period: period,
- });
- // Check to see if the default value for a range field works
- expect(newUser.acceptable_marks.length).to.equal(2);
- expect(newUser.acceptable_marks[0].value).to.equal('0.65'); // lower bound
- expect(newUser.acceptable_marks[1].value).to.equal('1'); // upper bound
- expect(newUser.acceptable_marks[0].inclusive).to.deep.equal(true); // inclusive
- expect(newUser.acceptable_marks[1].inclusive).to.deep.equal(false); // exclusive
- expect(newUser.course_period[0].value instanceof Date).to.be.ok; // lower bound
- expect(newUser.course_period[1].value instanceof Date).to.be.ok; // upper bound
- expect(newUser.course_period[0].value).to.equalTime(period[0]); // lower bound
- expect(newUser.course_period[1].value).to.equalTime(period[1]); // upper bound
- expect(newUser.course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(newUser.course_period[1].inclusive).to.deep.equal(false); // exclusive
- // Check to see if updating a range field works
- await newUser.update({ acceptable_marks: [0.8, 0.9] });
- await newUser.reload(); // Ensure the acceptable_marks array is loaded with the complete range definition
- expect(newUser.acceptable_marks.length).to.equal(2);
- expect(newUser.acceptable_marks[0].value).to.equal('0.8'); // lower bound
- expect(newUser.acceptable_marks[1].value).to.equal('0.9'); // upper bound
- });
- it('should save range array correctly', async function () {
- const User = this.User;
- const holidays = [
- [new Date(2015, 3, 1), new Date(2015, 3, 15)],
- [new Date(2015, 8, 1), new Date(2015, 9, 15)],
- ];
- await User.create({
- username: 'bob',
- email: ['myemail@email.com'],
- holidays,
- });
- const user = await User.findByPk(1);
- expect(user.holidays.length).to.equal(2);
- expect(user.holidays[0].length).to.equal(2);
- expect(user.holidays[0][0].value instanceof Date).to.be.ok;
- expect(user.holidays[0][1].value instanceof Date).to.be.ok;
- expect(user.holidays[0][0].value).to.equalTime(holidays[0][0]);
- expect(user.holidays[0][1].value).to.equalTime(holidays[0][1]);
- expect(user.holidays[1].length).to.equal(2);
- expect(user.holidays[1][0].value instanceof Date).to.be.ok;
- expect(user.holidays[1][1].value instanceof Date).to.be.ok;
- expect(user.holidays[1][0].value).to.equalTime(holidays[1][0]);
- expect(user.holidays[1][1].value).to.equalTime(holidays[1][1]);
- });
- it('should bulkCreate with range property', async function () {
- const User = this.User;
- const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];
- await User.bulkCreate([
- {
- username: 'bob',
- email: ['myemail@email.com'],
- course_period: period,
- },
- ]);
- const user = await User.findByPk(1);
- expect(user.course_period[0].value instanceof Date).to.be.ok;
- expect(user.course_period[1].value instanceof Date).to.be.ok;
- expect(user.course_period[0].value).to.equalTime(period[0]); // lower bound
- expect(user.course_period[1].value).to.equalTime(period[1]); // upper bound
- expect(user.course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(user.course_period[1].inclusive).to.deep.equal(false); // exclusive
- });
- it('should update range correctly', async function () {
- const User = this.User;
- const period = [new Date(2015, 0, 1), new Date(2015, 11, 31)];
- const newUser = await User.create({
- username: 'user',
- email: ['foo@bar.com'],
- course_period: period,
- });
- // Check to see if the default value for a range field works
- expect(newUser.acceptable_marks.length).to.equal(2);
- expect(newUser.acceptable_marks[0].value).to.equal('0.65'); // lower bound
- expect(newUser.acceptable_marks[1].value).to.equal('1'); // upper bound
- expect(newUser.acceptable_marks[0].inclusive).to.deep.equal(true); // inclusive
- expect(newUser.acceptable_marks[1].inclusive).to.deep.equal(false); // exclusive
- expect(newUser.course_period[0].value instanceof Date).to.be.ok;
- expect(newUser.course_period[1].value instanceof Date).to.be.ok;
- expect(newUser.course_period[0].value).to.equalTime(period[0]); // lower bound
- expect(newUser.course_period[1].value).to.equalTime(period[1]); // upper bound
- expect(newUser.course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(newUser.course_period[1].inclusive).to.deep.equal(false); // exclusive
- const period2 = [new Date(2015, 1, 1), new Date(2015, 10, 30)];
- // Check to see if updating a range field works
- await User.update({ course_period: period2 }, { where: newUser.where() });
- await newUser.reload();
- expect(newUser.course_period[0].value instanceof Date).to.be.ok;
- expect(newUser.course_period[1].value instanceof Date).to.be.ok;
- expect(newUser.course_period[0].value).to.equalTime(period2[0]); // lower bound
- expect(newUser.course_period[1].value).to.equalTime(period2[1]); // upper bound
- expect(newUser.course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(newUser.course_period[1].inclusive).to.deep.equal(false); // exclusive
- });
- it('should update range correctly and return the affected rows', async function () {
- const User = this.User;
- const period = [new Date(2015, 1, 1), new Date(2015, 10, 30)];
- const oldUser = await User.create({
- username: 'user',
- email: ['foo@bar.com'],
- course_period: [new Date(2015, 0, 1), new Date(2015, 11, 31)],
- });
- // Update the user and check that the returned object's fields have been parsed by the range parser
- const [count, users] = await User.update(
- { course_period: period },
- { where: oldUser.where(), returning: true },
- );
- expect(count).to.equal(1);
- expect(users[0].course_period[0].value instanceof Date).to.be.ok;
- expect(users[0].course_period[1].value instanceof Date).to.be.ok;
- expect(users[0].course_period[0].value).to.equalTime(period[0]); // lower bound
- expect(users[0].course_period[1].value).to.equalTime(period[1]); // upper bound
- expect(users[0].course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(users[0].course_period[1].inclusive).to.deep.equal(false); // exclusive
- });
- it('should read range correctly', async function () {
- const User = this.User;
- const course_period = [
- { value: new Date(2015, 1, 1), inclusive: false },
- { value: new Date(2015, 10, 30), inclusive: false },
- ];
- const data = { username: 'user', email: ['foo@bar.com'], course_period };
- await User.create(data);
- const user = await User.findOne({ where: { username: 'user' } });
- // Check that the range fields are the same when retrieving the user
- expect(user.course_period).to.deep.equal(data.course_period);
- });
- it('should read range array correctly', async function () {
- const User = this.User;
- const holidays = [
- [
- { value: new Date(2015, 3, 1, 10), inclusive: true },
- { value: new Date(2015, 3, 15), inclusive: true },
- ],
- [
- { value: new Date(2015, 8, 1), inclusive: true },
- { value: new Date(2015, 9, 15), inclusive: true },
- ],
- ];
- const data = { username: 'user', email: ['foo@bar.com'], holidays };
- await User.create(data);
- // Check that the range fields are the same when retrieving the user
- const user = await User.findOne({ where: { username: 'user' } });
- expect(user.holidays).to.deep.equal(data.holidays);
- });
- it('should read range correctly from multiple rows', async function () {
- const User = this.User;
- const periods = [
- [new Date(2015, 0, 1), new Date(2015, 11, 31)],
- [new Date(2016, 0, 1), new Date(2016, 11, 31)],
- ];
- await User.create({ username: 'user1', email: ['foo@bar.com'], course_period: periods[0] });
- await User.create({ username: 'user2', email: ['foo2@bar.com'], course_period: periods[1] });
- // Check that the range fields are the same when retrieving the user
- const users = await User.findAll({ order: ['username'] });
- expect(users[0].course_period[0].value).to.equalTime(periods[0][0]); // lower bound
- expect(users[0].course_period[1].value).to.equalTime(periods[0][1]); // upper bound
- expect(users[0].course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(users[0].course_period[1].inclusive).to.deep.equal(false); // exclusive
- expect(users[1].course_period[0].value).to.equalTime(periods[1][0]); // lower bound
- expect(users[1].course_period[1].value).to.equalTime(periods[1][1]); // upper bound
- expect(users[1].course_period[0].inclusive).to.deep.equal(true); // inclusive
- expect(users[1].course_period[1].inclusive).to.deep.equal(false); // exclusive
- });
- it('should read range correctly from included models as well', async function () {
- const period = [new Date(2016, 0, 1), new Date(2016, 11, 31)];
- const HolidayDate = this.sequelize.define('holidayDate', {
- period: DataTypes.RANGE(DataTypes.DATE),
- });
- this.User.hasMany(HolidayDate);
- await this.sequelize.sync({ force: true });
- const user0 = await this.User.create({ username: 'user', email: ['foo@bar.com'] });
- const holidayDate = await HolidayDate.create({ period });
- await user0.setHolidayDates([holidayDate]);
- const user = await this.User.findOne({ where: { username: 'user' }, include: [HolidayDate] });
- expect(user.hasOwnProperty('holidayDates')).to.be.ok;
- expect(user.holidayDates.length).to.equal(1);
- expect(user.holidayDates[0].period.length).to.equal(2);
- expect(user.holidayDates[0].period[0].value).to.equalTime(period[0]);
- expect(user.holidayDates[0].period[1].value).to.equalTime(period[1]);
- });
- });
- it('should save geometry correctly', async function () {
- const point = { type: 'Point', coordinates: [39.807_222, -76.984_722] };
- const newUser = await this.User.create({
- username: 'user',
- email: ['foo@bar.com'],
- location: point,
- });
- expect(newUser.location).to.deep.include(point);
- });
- it('should update geometry correctly', async function () {
- const User = this.User;
- const point1 = { type: 'Point', coordinates: [39.807_222, -76.984_722] };
- const point2 = { type: 'Point', coordinates: [39.828_333, -77.232_222] };
- const oldUser = await User.create({
- username: 'user',
- email: ['foo@bar.com'],
- location: point1,
- });
- const [, updatedUsers] = await User.update(
- { location: point2 },
- { where: { username: oldUser.username }, returning: true },
- );
- expect(updatedUsers[0].location).to.deep.include(point2);
- });
- it('should read geometry correctly', async function () {
- const User = this.User;
- const point = { type: 'Point', coordinates: [39.807_222, -76.984_722] };
- const user0 = await User.create({ username: 'user', email: ['foo@bar.com'], location: point });
- const user = await User.findOne({ where: { username: user0.username } });
- expect(user.location).to.deep.include(point);
- });
- });
|