Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade testing envronment #141

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ spec/
coverage
jest.config.js
jest.setup.js
jest.logger.js
tsconfig.json
tsconfig.spec.json

Expand Down
102 changes: 102 additions & 0 deletions jest.logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
const moment = require('moment');
const {inspect} = require('util');

class JestLogger {

/**
* @param {{dateFormat:string=,logLevel:string=,format:raw=}=} options
*/
constructor(options) {
this.options = Object.assign({}, {
dateFormat: 'DD/MMM/YYYY:HH:mm:ss Z',
logLevel: 'info',
format: 'raw'
}, options);
if (options == null) {
// validate NODE_ENV environment variable
if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') {
this.options.logLevel = 'debug';
}
}
this.level = JestLogger.Levels.info;
if (Object.prototype.hasOwnProperty.call(JestLogger.Levels), this.options.logLevel) {
this.level = JestLogger.Levels[this.options.logLevel];
}

}

static get Levels() {
return {
error: 0,
warn: 1,
info: 2,
verbose: 3,
debug: 4
};
}

log() {
if (this.level < JestLogger.Levels.info) {
return;
}
this.write.apply(this, ['log'].concat(Array.from(arguments)));
}

info() {
if (this.level < JestLogger.Levels.info) {
return;
}
this.write.apply(this, ['info'].concat(Array.from(arguments)));
}

warn() {
if (this.level < JestLogger.Levels.warn) {
return;
}
this.write.apply(this, ['warn'].concat(Array.from(arguments)));
}

error() {
if (this.level < JestLogger.Levels.error) {
return;
}
this.write.apply(this, ['error'].concat(Array.from(arguments)));
}

verbose() {
if (this.level < JestLogger.Levels.verbose) {
return;
}
this.write.apply(this, ['verbose'].concat(Array.from(arguments)));
}

debug() {
if (this.level < JestLogger.Levels.debug) {
return;
}
this.write.apply(this, ['debug'].concat(Array.from(arguments)));
}

/**
* @param {string} level
* @param {...*} arg
*/
// eslint-disable-next-line no-unused-vars
write(level, arg) {
const args = Array.from(arguments);
const log = (level === 'error') ? process.stderr : process.stdout
if (args.length > 1) {
if (args[args.length - 1] == null) {
args.pop();
}
}
// add timestamp
args.unshift(moment().format(this.options.dateFormat || 'DD/MMM/YYYY:HH:mm:ss Z'));
log.write(args.map((arg) => inspect(arg)).map(
(arg) => arg.replace(/^'/, '').replace(/'$/, '')
).join(',') + '\n');
}
}
// use JestLogger as default logger

module.exports = JestLogger;
16 changes: 3 additions & 13 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
require('source-map-support/register');
require('./data-model');

const {TraceUtils} = require('@themost/common');
const JestLogger = require('./jest.logger');
TraceUtils.useLogger(new JestLogger());
/* global jest */
require('dotenv').config();
Object.assign(global.console , {
// uncomment to ignore a specific log level
// eslint-disable-next-line no-undef
// log: jest.fn(),
// debug: jest.fn(),
// info: jest.fn(),
// warn: jest.fn(),
// error: jest.fn(),
});
jest.setTimeout(30000);
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "@themost/data",
"version": "2.11.3",
"version": "2.11.4",
"description": "MOST Web Framework Codename Blueshift - Data module",
"main": "index.js",
"scripts": {
"test": "jest",
"install-peers": "add-peers"
},
"peerDependencies": {
"@themost/common": "^2.10.3",
"@themost/query": ">=2.11.0",
"@themost/common": "^2.10.4",
"@themost/query": ">=2.11.2",
"@themost/xml": "^2"
},
"engines": {
Expand Down
3 changes: 2 additions & 1 deletion spec/CustomQueryExpr.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {TestUtils} from './adapter/TestUtils';
import { TestApplication2 } from './TestApplication';
import { DataContext } from '../types';
import { DataConfigurationStrategy } from '../data-configuration';
import {SqliteAdapter} from '@themost/sqlite';

const TempOrderSchema = {
"name": "TempOrder",
Expand Down Expand Up @@ -445,7 +446,7 @@ describe('CustomQueryExpression', () => {
const ExtendedProducts = context.model('ExtendedProduct');
await ExtendedProducts.migrateAsync();
// validate non-insertable columns
const db: TestAdapter = context.db as TestAdapter;
const db: SqliteAdapter = context.db as SqliteAdapter;
const columns = await db.table(ExtendedProducts.sourceAdapter).columnsAsync();
expect(columns.find((item) => item.name === 'priceCategory')).toBeFalsy();
// insert a temporary object
Expand Down
1 change: 0 additions & 1 deletion spec/DataModel.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {DataModel, EdmMapping, DataContext} from '../index';
import { TestApplication } from './TestApplication';
import { resolve } from 'path';
import { TestAdapter } from './adapter/TestAdapter';

class Employee {
public EmployeeID?: number;
Expand Down
22 changes: 4 additions & 18 deletions spec/DataObjectTag.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {resolve} from 'path';
import {TestUtils} from './adapter/TestUtils';
import {TestApplication, TestApplication2} from './TestApplication';
import {DataContext} from '../types';
import {DataObject} from '../data-object';
import {DataObjectTag} from '../data-object-tag';

describe('DataObjectTag', () => {
let app: TestApplication;
Expand All @@ -21,9 +22,6 @@ describe('DataObjectTag', () => {
}
});
await TestUtils.executeInTransaction(context, async () => {
/**
* @type {DataObject}
*/
let user = await context.model('User').where('name').equal('luis.nash@example.com').getTypedItem();
await user.property('tags').insert([
'NewUser',
Expand All @@ -49,9 +47,6 @@ describe('DataObjectTag', () => {
}
});
await TestUtils.executeInTransaction(context, async () => {
/**
* @type {DataObject}
*/
let user = await context.model('User').where('name').equal('luis.nash@example.com').getTypedItem();
await expect(user.property('tags').insert([
'NewUser',
Expand Down Expand Up @@ -82,9 +77,6 @@ describe('DataObjectTag', () => {
}
});
await TestUtils.executeInTransaction(context, async () => {
/**
* @type {DataObject}
*/
let user = await context.model('User').where('name').equal('luis.nash@example.com').getTypedItem();
await user.property('tags').insert([
'NewUser',
Expand Down Expand Up @@ -129,18 +121,15 @@ describe('DataObjectTag', () => {
}
});
await TestUtils.executeInTransaction(context, async () => {
/**
* @type {DataObject}
*/
let user = await context.model('User').where('name').equal('luis.nash@example.com').getTypedItem();
await user.property('tags').silent().insert([
const tags: DataObjectTag = user.property('tags').silent();
await tags.insert([
'NewUser',
'ValidUser'
]);
await expect(user.property('tags').remove([
'ValidUser'
])).rejects.toThrowError('Access Denied');

user = await context.model('User')
.where('name').equal('luis.nash@example.com')
.expand('tags')
Expand All @@ -161,9 +150,6 @@ describe('DataObjectTag', () => {
}
});
await TestUtils.executeInTransaction(context, async () => {
/**
* @type {DataObject}
*/
let user = await context.model('User').where('name').equal('luis.nash@example.com').getTypedItem();
await user.property('tags').silent().insert([
'NewUser',
Expand Down
8 changes: 4 additions & 4 deletions spec/DataPrivilege.exclude.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {TestUtils} from './adapter/TestUtils';
import { TestApplication2 } from './TestApplication';
import { DataContext } from '../types';
import {DataAdapter, DataContext} from '../types';
import {DataModelFilterParser} from '../data-model-filter.parser';
import { at } from 'lodash';
import { DataPermissionExclusion } from '../data-permission';
Expand Down Expand Up @@ -69,7 +69,7 @@ describe('DataPrivilege', () => {
$expand: q1.$expand,
// $fixed: true
});
let result: any[] = await (context.db as TestAdapter).executeAsync(queryUsers.query);
let result: any[] = await (context.db as DataAdapter).executeAsync(queryUsers.query, []);
expect(result.length).toBeTruthy();

q1 = await parser.parseAsync('indexof(context/user/authenticationScope, \'profile\') eq 0');
Expand All @@ -80,7 +80,7 @@ describe('DataPrivilege', () => {
$expand: q1.$expand,
// $fixed: true
});
result = await (context.db as TestAdapter).executeAsync(queryUsers.query);
result = await (context.db as DataAdapter).executeAsync(queryUsers.query, []);
expect(result.length).toBeTruthy();

});
Expand Down Expand Up @@ -129,4 +129,4 @@ describe('DataPrivilege', () => {
items = await context.model('Order').where('customer/email').equal('luis.nash@example.com').getItems();
expect(items.length).toBeTruthy();
});
});
});
107 changes: 107 additions & 0 deletions spec/DataPrivileges.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { resolve } from 'path';
import { DataContext } from '../index';
import { TestApplication, TestApplication2 } from './TestApplication';

describe('Permissions', () => {
let app: TestApplication;
let context: DataContext;
beforeAll(async () => {
app = new TestApplication2();
context = app.createContext();
});
afterAll(async () => {
await context.finalizeAsync();
await app.finalize();
});

it('should validate read access', async () => {
const Products = context.model('Product');
const items = await Products.getItems();
expect(Array.isArray(items)).toBeTruthy();
expect(items.length).toBeTruthy();
});

it('should validate write access', async () => {
const Products = context.model('Product');
const item = await Products.where('name').equal(
'Apple MacBook Air (13.3-inch, 2013 Version)'
).getItem();
expect(item).toBeTruthy();
expect(item.name).toBe('Apple MacBook Air (13.3-inch, 2013 Version)');
item.model = 'APPLE-MACBOOK-AIR-13.3-2013';
await expect(Products.save(item)).rejects.toThrow('Access Denied');
});

it('should validate create access', async () => {
const Products = context.model('Product');
// set context user
Object.assign(context, {
user: {
name: 'christina.ali@example.com'
}});
const orderedItem = await Products.where('name').equal(
'Apple MacBook Air (13.3-inch, 2013 Version)'
).getItem();
expect(orderedItem).toBeTruthy();
const customer = await context.model('People').where('user/name')
.equal('christina.ali@example.com')
.getItem();
expect(customer).toBeTruthy();
const Orders = context.model('Order');
let newOrder = {
orderedItem,
customer
};
await expect(Orders.save(newOrder)).resolves.toBeTruthy();
// try to place an order with different status (should fail)
const orderStatus = {
name: 'Pickup'
}
await expect(Orders.save({
orderedItem,
customer,
orderStatus
})).rejects.toThrow('Access Denied');
});

it('should validate update access', async () => {
await context.model('ActionStatusType').getItems()
const Products = context.model('Product');
const user = {
name: 'margaret.davis@example.com'
}
// add user to contributors
const group = await context.model('Group').where('name').equal('Contributors').getTypedItem();
expect(group).toBeTruthy();
const members = group.property('members').silent();
await members.insert(user);
Object.assign(context, {
user
});
const user1 = await context.model('User').find(user)
.expand('groups').silent().getItem();
expect(user1).toBeTruthy();
expect(user1.groups).toBeTruthy();
const orderedItem = await Products.where('name').equal(
'Lenovo Yoga 2 Pro'
).getItem();
expect(orderedItem).toBeTruthy();
const customer = await context.model('People').where('user/name')
.equal('christina.ali@example.com')
.getItem();
expect(customer).toBeTruthy();
const agent = await context.model('People').where('user/name')
.equal(user.name)
.getItem();
expect(agent).toBeTruthy();
const OrderActions = context.model('OrderAction');
let newAction = {
orderedItem,
customer,
agent
};
await expect(OrderActions.save(newAction)).resolves.toBeTruthy();

});

});
Loading