#424 Plus tests fixes

This commit is contained in:
Juan Ferrer 2018-12-19 08:42:07 +01:00
parent e1a7567648
commit f89cb0e661
18 changed files with 230 additions and 228 deletions

View File

@ -1,6 +0,0 @@
{
"salixHost": "localhost",
"salixPort": "3306",
"salixUser": "root",
"salixPassword": "root"
}

View File

@ -26,7 +26,7 @@ rules:
bracketSpacing: 0
space-infix-ops: 1
prefer-const: 0
curly: [error, multi, consitent]
curly: [error, multi-or-nest]
indent: [error, 4]
arrow-parens: [error, as-needed]
jasmine/no-focused-tests: 0

6
Jenkinsfile vendored
View File

@ -5,14 +5,10 @@ env.COMPOSER_HTTP_TIMEOUT = 300;
switch (env.BRANCH_NAME) {
case 'test':
env.NODE_ENV = 'test';
env.salixHost = env.testSalixHost;
env.salixPort = env.testSalixPort;
break;
case 'master':
env.NODE_ENV = 'production'
env.salixHost = env.productionSalixHost;
env.salixPort = env.productionSalixPort;
env.DOCKER_HOST = 'tcp://vch1.verdnatura.es:2375';
env.DOCKER_HOST = 'tcp://vch1.verdnatura.es:2376';
break;
}

View File

@ -2,7 +2,7 @@ import ngModule from '../module';
import './item-client';
export default class Controller {
constructor($scope) {
constructor($scope, $stateParams) {
this.$ = $scope;
this.clientSelected = null;
}
@ -38,7 +38,7 @@ export default class Controller {
this.$.dialogSummaryClient.show();
}
}
Controller.$inject = ['$scope'];
Controller.$inject = ['$scope', '$stateParams'];
ngModule.component('vnClientIndex', {
template: require('./index.html'),

View File

@ -21,26 +21,40 @@ export default class Controller extends Component {
super($element, $scope);
this.$compile = $compile;
this.$state = $state;
this.deregisterCallback = $transitions.onStart({},
transition => this.changeState(transition));
this.filter = {};
let criteria = {to: this.$state.current.name};
this.deregisterCallback = $transitions.onSuccess(criteria,
() => this.onStateChange());
this._filter = null;
this.searchString = '';
this.autoLoad = false;
}
$onInit() {
if (this.$state.params.q)
this.filter = JSON.parse(decodeURIComponent(this.$state.params.q));
this.refreshString();
if (this.autoLoad || !angular.equals({}, this.filter))
this.doSearch();
$postLink() {
if (this.filter === null)
this.onStateChange();
}
changeState(transition) {
return transition._targetState._identifier.name !== this.$state.current.name;
set filter(value) {
this._filter = value;
this.pushFilterToState(value);
}
get filter() {
return this._filter;
}
onStateChange() {
this._filter = null;
if (this.$state.params.q) {
try {
this._filter = JSON.parse(this.$state.params.q);
} catch (e) {}
}
this.doSearch();
}
openPanel(event) {
@ -49,7 +63,7 @@ export default class Controller extends Component {
this.$panel = this.$compile(`<${this.panel}/>`)(this.$.$new());
let panel = this.$panel.isolateScope().$ctrl;
panel.filter = this.filter;
panel.filter = this._filter;
panel.onSubmit = filter => this.onPanelSubmit(filter);
this.$.popover.parent = this.element;
@ -72,85 +86,78 @@ export default class Controller extends Component {
}
this.filter = filter;
this.refreshString();
this.doSearch();
}
refreshString() {
this.searchString = this.getStringFromObject(this.filter);
}
onSubmit() {
this.filter = this.getObjectFromString(this.searchString);
this.doSearch();
}
doSearch() {
this.pushFilterToState(this.filter);
let filter = this._filter;
if (filter === null && this.autoload)
filter = {};
this.searchString = this.getStringFromObject(filter);
if (this.onSearch)
this.onSearch({$params: this.filter});
this.onSearch({$params: filter});
if (this.model) {
let where = buildFilter(this.filter,
(param, value) => this.exprBuilder({param, value}));
if (filter !== null) {
let where = buildFilter(filter,
(param, value) => this.exprBuilder({param, value}));
let userParams = {};
let hasParams = false;
let userParams = {};
let hasParams = false;
if (this.paramBuilder) {
for (let param in this.filter) {
let value = this.filter[param];
if (value == null) continue;
let expr = this.paramBuilder({param, value});
if (expr) {
Object.assign(userParams, expr);
hasParams = true;
if (this.paramBuilder) {
for (let param in filter) {
let value = filter[param];
if (value == null) continue;
let expr = this.paramBuilder({param, value});
if (expr) {
Object.assign(userParams, expr);
hasParams = true;
}
}
}
}
this.model.applyFilter(
where ? {where} : null,
hasParams ? userParams : null
);
this.model.applyFilter(
where ? {where} : null,
hasParams ? userParams : null
);
} else
this.model.clear();
}
}
exprBuilder(param, value) {
return {[param]: value};
}
pushFilterToState(filter) {
let state = window.location.hash.split('?')[0];
let keys = Object.keys(filter);
let search = {};
if (keys.length) {
let hashFilter = {};
keys.forEach(key => {
let value = filter[key];
if (value instanceof Date)
hashFilter[key] = value;
search[key] = value;
else {
switch (typeof value) {
case 'boolean':
case 'number':
case 'string':
case 'boolean':
hashFilter[key] = value;
search[key] = value;
}
}
});
let search = encodeURIComponent(JSON.stringify(hashFilter));
state += `?q=${search}`;
}
if (!window.history)
throw new Error('Browser incompatibility: window.history not found');
this.$state.go('.', {q: JSON.stringify(search)});
}
window.history.pushState({}, null, state);
exprBuilder(param, value) {
return {[param]: value};
}
/**

View File

@ -58,4 +58,5 @@ Botanical: Botánico
Barcodes: Códigos de barras
Diary: Registro
Item diary: Registro de compra-venta
Last entries: Últimas entradas
Last entries: Últimas entradas
Tags: Etiquetas

View File

@ -25,7 +25,7 @@
</vn-auto>
<vn-one margin-medium>
<vn-vertical name="basicData">
<h5 translate>Basic data (I)</h5>
<h5 translate>Basic data</h5>
<vn-label-value label="Name"
value="{{$ctrl.summary.item.name}}">
</vn-label-value>
@ -50,8 +50,8 @@
</vn-vertical>
</vn-one>
<vn-one margin-medium>
<vn-vertical name="basicData">
<h5 translate>Basic data (II)</h5>
<vn-vertical name="otherData">
<h5 translate>Other data</h5>
<vn-label-value label="Intrastat code"
value="{{$ctrl.summary.item.intrastat.id}}">
</vn-label-value>

View File

@ -1,2 +1,3 @@
Niche: Nichos
Barcode: Códigos de barras
Barcode: Códigos de barras
Other data: Otros datos

View File

@ -1,9 +1,10 @@
<vn-crud-model auto-load="false"
<vn-crud-model
vn-id="model"
url="/ticket/api/Tickets/filter"
limit="20"
data="tickets"
order="shipped DESC">
order="shipped DESC"
auto-load="false">
</vn-crud-model>
<div margin-medium>
<div class="vn-list">
@ -12,8 +13,7 @@
<vn-three>
<vn-searchbar
panel="vn-ticket-search-panel"
on-search="model.applyFilter(null, $params);"
filter="$ctrl.filter"
on-search="$ctrl.onSearch($params)"
vn-focus>
</vn-searchbar>
</vn-three>

View File

@ -16,10 +16,19 @@ export default class Controller {
today.setTime(today.getTime() - offset);
let tomorrow = new Date(today);
tomorrow.setHours(23, 59, 59, 59);
tomorrow.setHours(23, 59, 59, 999);
tomorrow.setTime(tomorrow.getTime() - offset);
this.filter = {myTeam: true, from: today, to: tomorrow};
// FIXME: History loop
// let filter = {myTeam: true, from: today, to: tomorrow};
// $state.go('.', {q: JSON.stringify(filter)});
}
onSearch(params) {
if (params)
this.$.model.applyFilter(null, params);
else
this.$.model.clear();
}
goToTurns() {

View File

@ -4,19 +4,16 @@ process.on('warning', warning => {
console.log(warning.stack);
});
var verbose = false;
let verbose = false;
if (process.argv[2] === '--v') {
if (process.argv[2] === '--v')
verbose = true;
}
servicesDir = `${__dirname}/services/db`;
var Jasmine = require('jasmine');
var jasmine = new Jasmine();
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let environment = require('gulp-env');
environment(".env.json");
let Jasmine = require('jasmine');
let jasmine = new Jasmine();
let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let serviceSpecs = [
'db/tests/**/*[sS]pec.js'

View File

@ -1,43 +1,41 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare';
describe('Ticket', () => {
describe('Create notes path', () => {
const nightmare = createNightmare();
describe('Ticket Create notes path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.loginAndModule('employee', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.observation');
});
beforeAll(() => {
return nightmare
.loginAndModule('employee', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.observation');
});
it(`should click create a new note and delete a former one`, async () => {
let result = await nightmare
.waitToClick(selectors.ticketNotes.firstNoteRemoveButton)
.waitToClick(selectors.ticketNotes.addNoteButton)
.waitToClick(selectors.ticketNotes.firstNoteSelect)
.waitToClick(selectors.ticketNotes.firstNoteSelectSecondOption)
.type(selectors.ticketNotes.firstDescriptionInput, 'description')
.click(selectors.ticketNotes.submitNotesButton)
.waitForLastSnackbar();
it(`should click create a new note and delete a former one`, async () => {
let result = await nightmare
.waitToClick(selectors.ticketNotes.firstNoteRemoveButton)
.waitToClick(selectors.ticketNotes.addNoteButton)
.waitToClick(selectors.ticketNotes.firstNoteSelect)
.waitToClick(selectors.ticketNotes.firstNoteSelectSecondOption)
.type(selectors.ticketNotes.firstDescriptionInput, 'description')
.click(selectors.ticketNotes.submitNotesButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
expect(result).toEqual('Data saved!');
});
it(`should confirm the note is the expected one`, async () => {
let firstNoteSelect = await nightmare
.click(selectors.ticketPackages.packagesButton)
.wait(selectors.ticketPackages.firstPackageSelect)
.click(selectors.ticketNotes.notesButton)
.waitToGetProperty(selectors.ticketNotes.firstNoteSelect, 'value');
it(`should confirm the note is the expected one`, async () => {
let firstNoteSelect = await nightmare
.click(selectors.ticketPackages.packagesButton)
.wait(selectors.ticketPackages.firstPackageSelect)
.click(selectors.ticketNotes.notesButton)
.waitToGetProperty(selectors.ticketNotes.firstNoteSelect, 'value');
expect(firstNoteSelect).toEqual('observation one');
expect(firstNoteSelect).toEqual('observation one');
let firstDescription = await nightmare
.waitToGetProperty(selectors.ticketNotes.firstDescriptionInput, 'value');
let firstDescription = await nightmare
.waitToGetProperty(selectors.ticketNotes.firstDescriptionInput, 'value');
expect(firstDescription).toEqual('description');
});
expect(firstDescription).toEqual('description');
});
});

View File

@ -1,28 +1,26 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare';
describe('Ticket', () => {
describe('Delete expeditions path', () => {
const nightmare = createNightmare();
describe('Ticket Delete expeditions path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.loginAndModule('production', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.expedition');
});
beforeAll(() => {
return nightmare
.loginAndModule('production', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.expedition');
});
it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async () => {
const result = await nightmare
.waitToClick(selectors.ticketExpedition.secondExpeditionRemoveButton)
.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton)
.click(selectors.ticketPackages.packagesButton)
.wait(selectors.ticketPackages.firstPackageSelect)
.click(selectors.ticketExpedition.expeditionButton)
.wait(selectors.ticketExpedition.expeditionRow)
.countElement(selectors.ticketExpedition.expeditionRow);
it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async () => {
const result = await nightmare
.waitToClick(selectors.ticketExpedition.secondExpeditionRemoveButton)
.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton)
.click(selectors.ticketPackages.packagesButton)
.wait(selectors.ticketPackages.firstPackageSelect)
.click(selectors.ticketExpedition.expeditionButton)
.wait(selectors.ticketExpedition.expeditionRow)
.countElement(selectors.ticketExpedition.expeditionRow);
expect(result).toEqual(3);
});
expect(result).toEqual(3);
});
});

View File

@ -1,62 +1,60 @@
import selectors from '../../helpers/selectors.js';
import createNightmare from '../../helpers/nightmare';
describe('Ticket', () => {
describe('Create new tracking state path', () => {
const nightmare = createNightmare();
describe('Ticket Create new tracking state path', () => {
const nightmare = createNightmare();
beforeAll(() => {
return nightmare
.loginAndModule('production', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.tracking.index');
});
beforeAll(() => {
return nightmare
.loginAndModule('production', 'ticket')
.accessToSearchResult('id:1')
.accessToSection('ticket.card.tracking.index');
});
it('should access to the create state view by clicking the create floating button', async () => {
let url = await nightmare
.waitToClick(selectors.ticketTracking.createStateButton)
.wait(selectors.createStateView.stateInput)
.parsedUrl();
it('should access to the create state view by clicking the create floating button', async () => {
let url = await nightmare
.waitToClick(selectors.ticketTracking.createStateButton)
.wait(selectors.createStateView.stateInput)
.parsedUrl();
expect(url.hash).toContain('tracking/edit');
});
expect(url.hash).toContain('tracking/edit');
});
it(`should attempt create a new state but receive an error if state is empty`, async () => {
let result = await nightmare
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
it(`should attempt create a new state but receive an error if state is empty`, async () => {
let result = await nightmare
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
expect(result).toEqual('No changes to save');
});
expect(result).toEqual('No changes to save');
});
it(`should attempt create a new state then clear and save it`, async () => {
let result = await nightmare
.waitToClick(selectors.createStateView.stateInput)
.waitToClick(selectors.createStateView.stateInputOptionOne)
.waitToClick(selectors.createStateView.clearStateInputButton)
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
it(`should attempt create a new state then clear and save it`, async () => {
let result = await nightmare
.waitToClick(selectors.createStateView.stateInput)
.waitToClick(selectors.createStateView.stateInputOptionOne)
.waitToClick(selectors.createStateView.clearStateInputButton)
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
expect(result).toEqual('Data saved!');
});
it('should again access to the create state view by clicking the create floating button', async () => {
let url = await nightmare
.click(selectors.ticketTracking.createStateButton)
.wait(selectors.createStateView.stateInput)
.parsedUrl();
it('should again access to the create state view by clicking the create floating button', async () => {
let url = await nightmare
.click(selectors.ticketTracking.createStateButton)
.wait(selectors.createStateView.stateInput)
.parsedUrl();
expect(url.hash).toContain('tracking/edit');
});
expect(url.hash).toContain('tracking/edit');
});
it(`should create a new state`, async () => {
let result = await nightmare
.waitToClick(selectors.createStateView.stateInput)
.waitToClick(selectors.createStateView.stateInputOptionOne)
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
it(`should create a new state`, async () => {
let result = await nightmare
.waitToClick(selectors.createStateView.stateInput)
.waitToClick(selectors.createStateView.stateInputOptionOne)
.click(selectors.createStateView.saveStateButton)
.waitForLastSnackbar();
expect(result).toEqual('Data saved!');
});
expect(result).toEqual('Data saved!');
});
});

View File

@ -1,4 +1,4 @@
var webpackConfig = require('./webpack.config.js');
let webpackConfig = require('./webpack.config.js');
delete webpackConfig.entry;
delete webpackConfig.output;
webpackConfig.devtool = 'inline-source-map';
@ -10,19 +10,19 @@ webpackConfig.plugins = [];
module.exports = function(config) {
let baseConfig = {
// base path that will be used to resolve all patterns (eg. files, exclude)
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
// list of files / patterns to load in the browser
files: [
{pattern: 'client/test_index.js', watched: false}
],
// list of files to exclude
// list of files to exclude
exclude: [],
webpack: webpackConfig,
@ -35,40 +35,40 @@ module.exports = function(config) {
noInfo: true
},
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'./client/test_index.js': ['webpack', 'sourcemap']
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [],
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['ChromeNoSandboxHeadless'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
plugins: [
@ -100,8 +100,6 @@ module.exports = function(config) {
if (process.env.FIREFOX_BIN)
baseConfig.browsers = ['FirefoxHeadless'];
else
baseConfig.browsers = ['ChromeNoSandboxHeadless'];
config.set(baseConfig);
};

View File

@ -20,5 +20,6 @@
"The sales of this ticket can't be modified": "The sales of this ticket can't be modified",
"Cannot check VIES and Equalization Tax": "Cannot check VIES and Equalization Tax",
"Cannot check Equalization Tax in this NIF/CIF": "Cannot check Equalization Tax in this NIF/CIF",
"You can't create an order for a frozen client": "You can't create an order for a frozen client"
"You can't create an order for a frozen client": "You can't create an order for a frozen client",
"This address doesn't exist": "This address doesn't exist"
}

View File

@ -8,10 +8,14 @@ module.exports = Self => {
let model = this.app.models[this.modelName].definition;
let properties = model.properties;
let columnName;
let tableName;
let tableName = this.modelName;
let schema = null;
if (model.settings && model.settings.mysql)
tableName = model.settings.mysql.table;
if (model.settings && model.settings.mysql) {
let tableSplit = model.settings.mysql.table.split('.');
tableName = tableSplit.pop();
schema = tableSplit.pop() || null;
}
if (properties[column]) {
columnName = column;
@ -27,10 +31,13 @@ module.exports = Self => {
if (findColumn)
columnName = properties[findColumn].mysql.columnName;
let type = await this.rawSql(`
SELECT DISTINCT column_type FROM information_schema.columns
let type = await this.rawSql(
`SELECT DISTINCT column_type FROM information_schema.columns
WHERE table_name = ?
AND column_name = ?`, [tableName, columnName]);
AND table_schema = IFNULL(?, DATABASE())
AND column_name = ?`,
[tableName, schema, columnName]
);
if (!type) return;

View File

@ -5,19 +5,16 @@ process.on('warning', warning => {
console.log(warning.stack);
});
var verbose = false;
let verbose = false;
if (process.argv[2] === '--v') {
if (process.argv[2] === '--v')
verbose = true;
}
servicesDir = `${__dirname}/services`;
var Jasmine = require('jasmine');
var jasmine = new Jasmine();
var SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let environment = require('gulp-env');
environment(".env.json");
let Jasmine = require('jasmine');
let jasmine = new Jasmine();
let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
let serviceList = fs.readdirSync(servicesDir);
let serviceSpecs = [