Latest updates from IceHrmPro
This commit is contained in:
@@ -8,9 +8,9 @@ $dropDBCommand = 'echo "DROP DATABASE IF EXISTS ' . APP_DB . '"| mysql -u' . MYS
|
||||
$createDBCommand = 'echo "CREATE DATABASE '.APP_DB.'"| mysql -u'.MYSQL_ROOT_USER.' -p'.MYSQL_ROOT_PASS;
|
||||
|
||||
|
||||
echo "Drop DB Command:".$dropDBCommand."\r\n";
|
||||
//echo "Drop DB Command:".$dropDBCommand."\r\n";
|
||||
exec($dropDBCommand);
|
||||
echo "Create DB Command:".$createDBCommand."\r\n";
|
||||
//echo "Create DB Command:".$createDBCommand."\r\n";
|
||||
exec($createDBCommand);
|
||||
|
||||
//Run create table script
|
||||
@@ -20,9 +20,9 @@ $scripts = array(
|
||||
);
|
||||
|
||||
foreach ($scripts as $insql) {
|
||||
echo $insql."\r\n";
|
||||
//echo $insql."\r\n";
|
||||
$command = "cat ".$insql."| mysql -u".MYSQL_ROOT_USER." -p".MYSQL_ROOT_PASS." '".APP_DB."'";
|
||||
exec($command);
|
||||
}
|
||||
include(dirname(__FILE__).'/test.includes.php');
|
||||
echo "Bootstrapping done!!"."\r\n";
|
||||
//echo "Bootstrapping done!!"."\r\n";
|
||||
|
||||
5
test/frontend/.eslintrc
Normal file
5
test/frontend/.eslintrc
Normal file
@@ -0,0 +1,5 @@
|
||||
// Use this file as a starting point for your project's .eslintrc.
|
||||
// Copy this file, and add rule overrides as needed.
|
||||
{
|
||||
"extends": "airbnb"
|
||||
}
|
||||
4
test/frontend/cypress.json
Normal file
4
test/frontend/cypress.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"viewportWidth": 1280,
|
||||
"viewportHeight": 1024
|
||||
}
|
||||
112
test/frontend/cypress/commmon/ice-cypress-test.js
Normal file
112
test/frontend/cypress/commmon/ice-cypress-test.js
Normal file
@@ -0,0 +1,112 @@
|
||||
const config = require('../support/config');
|
||||
|
||||
class IceCypressTest {
|
||||
constructor(moduleUrl, element, isRemoteTable) {
|
||||
this.moduleUrl = moduleUrl;
|
||||
this.element = element;
|
||||
this.isRemoteTable = isRemoteTable;
|
||||
this.titleDataAttributeName = 'data-original-title';
|
||||
if (isRemoteTable) {
|
||||
this.titleDataAttributeName = 'title';
|
||||
}
|
||||
}
|
||||
|
||||
loadTable(cy, count = config.DEFAULT_MAX_PAGE_SIZE) {
|
||||
cy.get(`#${this.element} table tbody`).find('tr')
|
||||
.its('length').should('eq', count);
|
||||
}
|
||||
|
||||
viewElement(cy, viewButtonSelector = null) {
|
||||
cy.server().route('GET', `/${config.URL_PREFIX}/service.php*`).as('getElement');
|
||||
cy.get(`#${this.element} table tbody`).find('tr').first()
|
||||
.find(viewButtonSelector || `.center div img[${this.titleDataAttributeName}='View']`)
|
||||
.click();
|
||||
|
||||
cy.wait('@getElement').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
}
|
||||
|
||||
viewElementValidate(cy, validation = []) {
|
||||
validation.forEach((rule) => {
|
||||
cy.get(rule[0]).then(element => expect(element.text()).eq(rule[1]));
|
||||
});
|
||||
}
|
||||
|
||||
editElement(cy, update, editButtonSelector = null) {
|
||||
cy.server().route('POST', `/${config.URL_PREFIX}/service.php*`).as('getElement');
|
||||
cy.get(`#${this.element} table tbody`).find('tr').first().find(editButtonSelector || `.center div img[${this.titleDataAttributeName}='Edit']`)
|
||||
.click();
|
||||
|
||||
cy.wait('@getElement').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
|
||||
update.forEach((item) => {
|
||||
cy.get(item[0]).clear().type(item[1]).should('have.value', item[1]);
|
||||
});
|
||||
}
|
||||
|
||||
select2Click(id, value) {
|
||||
cy.get(`#s2id_${id}`).click();
|
||||
cy.focused().clear().type(value).should('have.value', value);
|
||||
cy.get('.select2-drop:visible').find('.select2-results li').first()
|
||||
.click();
|
||||
}
|
||||
|
||||
clickSave(cy) {
|
||||
cy.get(`#${this.element}Form .saveBtn`).click();
|
||||
}
|
||||
|
||||
editElementValidate(cy, validation = [], editButtonSelector) {
|
||||
if (this.isRemoteTable) {
|
||||
cy.server().route('GET', `/${config.URL_PREFIX}/data.php*`).as('getAfterSave');
|
||||
} else {
|
||||
cy.server().route('POST', `/${config.URL_PREFIX}/service.php*`).as('getAfterSave');
|
||||
}
|
||||
|
||||
// Wait for data table response
|
||||
cy.wait('@getAfterSave').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
|
||||
cy.server().route('POST', `/${config.URL_PREFIX}/service.php*`).as('getElementAfterSave');
|
||||
// Click on edit and wait
|
||||
cy.get(`#${this.element} table tbody`).find('tr').first().find(editButtonSelector || `.center div img[${this.titleDataAttributeName}='Edit']`)
|
||||
.click();
|
||||
|
||||
cy.wait('@getElementAfterSave').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
|
||||
validation.forEach((item) => {
|
||||
cy.get(item[0]).then(element => expect(element.val()).eq(item[1]));
|
||||
});
|
||||
}
|
||||
|
||||
canNotEditElement(cy, editButtonSelector = null) {
|
||||
cy.get(`#${this.element} table tbody`).find('tr')
|
||||
.first().find(editButtonSelector || ".center div img[title='Edit']")
|
||||
.should('not.exist');
|
||||
}
|
||||
|
||||
loadModule(cy) {
|
||||
// Request to watch and wait
|
||||
if (this.isRemoteTable) {
|
||||
cy.server().route('GET', `/${config.URL_PREFIX}/data.php*`).as('get');
|
||||
} else {
|
||||
cy.server().route('POST', `/${config.URL_PREFIX}/service.php*`).as('get');
|
||||
}
|
||||
|
||||
|
||||
// Visit module
|
||||
cy.visit(`${config.BASE_URL}?${this.moduleUrl}`);
|
||||
|
||||
// Wait for data table response
|
||||
cy.wait('@get').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
}
|
||||
|
||||
switchTab(cy, tabName = null) {
|
||||
if (this.isRemoteTable) {
|
||||
cy.server().route('GET', `/${config.URL_PREFIX}/data.php*`).as('getTab');
|
||||
} else {
|
||||
cy.server().route('POST', `/${config.URL_PREFIX}/service.php*`).as('getTab');
|
||||
}
|
||||
cy.get(tabName || `#tab${this.element}`).click();
|
||||
cy.wait('@getTab').its('status').should('be', config.DEFAULT_WAIT_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IceCypressTest;
|
||||
5
test/frontend/cypress/fixtures/example.json
Normal file
5
test/frontend/cypress/fixtures/example.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "Using fixtures to represent data",
|
||||
"email": "hello@cypress.io",
|
||||
"body": "Fixtures are a great way to mock data for responses to routes"
|
||||
}
|
||||
5
test/frontend/cypress/integration/1_reset.db.spec.js
Normal file
5
test/frontend/cypress/integration/1_reset.db.spec.js
Normal file
@@ -0,0 +1,5 @@
|
||||
context('Reset DB', () => {
|
||||
it('resets DB', () => {
|
||||
cy.resetDatabase();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
const IceCypressTest = require('../../commmon/ice-cypress-test');
|
||||
const config = require('../../support/config');
|
||||
|
||||
const test = new IceCypressTest(
|
||||
'g=admin&n=company_structure&m=admin_Admin',
|
||||
'CompanyStructure',
|
||||
);
|
||||
|
||||
context('Admin Company Structure Module - Company Structure Tab', () => {
|
||||
|
||||
it('admin can view list', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy, 9);
|
||||
});
|
||||
|
||||
it('admin can edit element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.editElement(cy, [['#address', 'Address 1']]);
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#address', 'Address 1']]);
|
||||
});
|
||||
|
||||
it('manager can view list', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy, 9);
|
||||
});
|
||||
|
||||
it('manager can not edit element', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.canNotEditElement(cy);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
const IceCypressTest = require('../../commmon/ice-cypress-test');
|
||||
|
||||
const test = new IceCypressTest(
|
||||
'g=admin&n=employees&m=admin_Employees',
|
||||
'EmployeeSkill',
|
||||
true,
|
||||
);
|
||||
|
||||
context('Admin Employee Module - Skills Tab', () => {
|
||||
|
||||
it('admin can view list', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
test.loadTable(cy, 2);
|
||||
});
|
||||
|
||||
it('admin can edit element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
test.editElement(cy, [['#details', 'Employee skill']]);
|
||||
test.select2Click('skill_id', 'Networking');
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#details', 'Employee skill']]);
|
||||
});
|
||||
});
|
||||
53
test/frontend/cypress/integration/admin/employee.spec.js
Normal file
53
test/frontend/cypress/integration/admin/employee.spec.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const IceCypressTest = require('../../commmon/ice-cypress-test');
|
||||
const config = require('../../support/config');
|
||||
|
||||
const test = new IceCypressTest(
|
||||
'g=admin&n=employees&m=admin_Employees',
|
||||
'Employee',
|
||||
true,
|
||||
);
|
||||
|
||||
context('Admin Employee Module - Employee Tab', () => {
|
||||
|
||||
it('admin can view list', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy);
|
||||
});
|
||||
|
||||
it('admin can view element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.viewElement(cy);
|
||||
test.viewElementValidate(cy, [['#name', 'IceHrm Employee']]);
|
||||
});
|
||||
|
||||
it('admin can edit element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.editElement(cy, [['#middle_name', 'Middle Name']]);
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#middle_name', 'Middle Name']]);
|
||||
});
|
||||
|
||||
it('manager can view list', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy);
|
||||
});
|
||||
|
||||
it('manager can view element', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.viewElement(cy);
|
||||
test.viewElementValidate(cy, [['#name', 'IceHrm Employee']]);
|
||||
});
|
||||
|
||||
it('manager can edit element', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.editElement(cy, [['#middle_name', 'Middle Name 1']]);
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#middle_name', 'Middle Name 1']]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
const IceCypressTest = require('../../commmon/ice-cypress-test');
|
||||
const config = require('../../support/config');
|
||||
|
||||
const test = new IceCypressTest(
|
||||
'g=admin&n=teams&m=admin_Employees',
|
||||
'TeamMembers',
|
||||
false,
|
||||
);
|
||||
|
||||
context('Admin Teams Module - Team Members Tab', () => {
|
||||
it('admin can view list', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
test.loadTable(cy, 2);
|
||||
});
|
||||
|
||||
it('admin can edit element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
cy.get('#TeamMembers table tbody').find('tr').first().find('.center div img[data-original-title=\'Edit\']')
|
||||
.click();
|
||||
test.select2Click('team', 'beta');
|
||||
test.clickSave(cy);
|
||||
});
|
||||
|
||||
it('manager can view list', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
test.loadTable(cy, 2);
|
||||
});
|
||||
|
||||
it('manager can edit element', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.switchTab(cy);
|
||||
cy.get('#TeamMembers table tbody').find('tr').first().find('.center div img[data-original-title=\'Edit\']')
|
||||
.click();
|
||||
test.select2Click('team', 'beta');
|
||||
test.clickSave(cy);
|
||||
});
|
||||
});
|
||||
40
test/frontend/cypress/integration/admin/teams.spec.js
Normal file
40
test/frontend/cypress/integration/admin/teams.spec.js
Normal file
@@ -0,0 +1,40 @@
|
||||
const IceCypressTest = require('../../commmon/ice-cypress-test');
|
||||
const config = require('../../support/config');
|
||||
|
||||
const test = new IceCypressTest(
|
||||
'g=admin&n=teams&m=admin_Employees',
|
||||
'Teams',
|
||||
false,
|
||||
);
|
||||
|
||||
context('Admin Teams Module - Teams Tab', () => {
|
||||
it('admin can view list', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy, 2);
|
||||
});
|
||||
|
||||
it('admin can edit element', () => {
|
||||
cy.login('admin', 'admin');
|
||||
test.loadModule(cy);
|
||||
test.editElement(cy, [['#description', 'creative designing team']]);
|
||||
test.select2Click('department', 'Head Office');
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#description', 'creative designing team']]);
|
||||
});
|
||||
|
||||
it('manager can view list', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.loadTable(cy, 2);
|
||||
});
|
||||
|
||||
it('manager can edit element', () => {
|
||||
cy.login('manager', config.DEFAULT_USER_PASS);
|
||||
test.loadModule(cy);
|
||||
test.editElement(cy, [['#description', 'creative designing team']]);
|
||||
test.select2Click('department', 'Head Office');
|
||||
test.clickSave(cy);
|
||||
test.editElementValidate(cy, [['#description', 'creative designing team']]);
|
||||
});
|
||||
});
|
||||
17
test/frontend/cypress/plugins/index.js
Normal file
17
test/frontend/cypress/plugins/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example plugins/index.js can be used to load plugins
|
||||
//
|
||||
// You can change the location of this file or turn off loading
|
||||
// the plugins file with the 'pluginsFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/plugins-guide
|
||||
// ***********************************************************
|
||||
|
||||
// This function is called when a project is opened or re-opened (e.g. due to
|
||||
// the project's config changing)
|
||||
|
||||
module.exports = (on, config) => {
|
||||
// `on` is used to hook into various events Cypress emits
|
||||
// `config` is the resolved Cypress config
|
||||
};
|
||||
38
test/frontend/cypress/support/commands.js
Normal file
38
test/frontend/cypress/support/commands.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const config = require('./config');
|
||||
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
||||
//
|
||||
//
|
||||
// -- This is a parent command --
|
||||
// Cypress.Commands.add("login", (email, password) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a child command --
|
||||
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is a dual command --
|
||||
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
||||
//
|
||||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
|
||||
Cypress.Commands.add('login', (user, password) => {
|
||||
cy.visit(`${config.BASE_URL}login.php`);
|
||||
cy.get('#username').type(user).should('have.value', user);
|
||||
cy.get('#password').type(password).should('have.value', password);
|
||||
cy.get('.btn').first().click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add('resetDatabase', () => {
|
||||
cy.exec('vagrant ssh -c \'cd /vagrant/core/robo; php robo.phar reset:db test; php robo.phar create:tables test; php robo.phar migrate:all test; php robo.phar execute:fixtures test\'');
|
||||
});
|
||||
13
test/frontend/cypress/support/config.js
Normal file
13
test/frontend/cypress/support/config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const BASE_URL = 'http://clients.icehrmpro.test/test/';
|
||||
const DEFAULT_MAX_PAGE_SIZE = 15;
|
||||
const DEFAULT_WAIT_TIME = 500;
|
||||
const DEFAULT_USER_PASS = 'demouserpwd';
|
||||
const URL_PREFIX = 'test';
|
||||
|
||||
module.exports = {
|
||||
BASE_URL,
|
||||
DEFAULT_MAX_PAGE_SIZE,
|
||||
DEFAULT_WAIT_TIME,
|
||||
DEFAULT_USER_PASS,
|
||||
URL_PREFIX,
|
||||
};
|
||||
20
test/frontend/cypress/support/index.js
Normal file
20
test/frontend/cypress/support/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
||||
|
||||
// Alternatively you can use CommonJS syntax:
|
||||
// require('./commands')
|
||||
1751
test/frontend/package-lock.json
generated
Normal file
1751
test/frontend/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
test/frontend/package.json
Normal file
18
test/frontend/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "icehrm-frontend-tests",
|
||||
"version": "0.0.0",
|
||||
"description": "",
|
||||
"main": "gulpfile.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"cypress": "^3.4.1",
|
||||
"eslint-config-airbnb": "^18.0.1"
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,9 @@ class ApprovalStatusIntegration extends \TestTemplate
|
||||
$emp->approver1 = $ids[4];
|
||||
$emp->approver2 = $ids[5];
|
||||
$emp->approver3 = $ids[6];
|
||||
$ok = $emp->Save();
|
||||
$emp->Save();
|
||||
|
||||
|
||||
|
||||
$this->travelRec = new EmployeeTravelRecord();
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: Thilina
|
||||
* Date: 9/17/17
|
||||
* Time: 7:06 PM
|
||||
*/
|
||||
|
||||
namespace Test\Integration;
|
||||
|
||||
use Classes\Migration\MigrationManager;
|
||||
use Model\Migration;
|
||||
|
||||
class MigrationManagerIntegration extends \TestTemplate
|
||||
{
|
||||
/* @var MigrationManager $migrationManager */
|
||||
private $migrationManager;
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
$this->migrationManager = new MigrationManager();
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
$migration = new Migration();
|
||||
$migration->file = 'migration'.$i;
|
||||
$migration->version = '190000';
|
||||
$migration->created = date("Y-m-d H:i:s", intval(time()) - 10 * $i);
|
||||
$migration->updated = date("Y-m-d H:i:s", intval(time()) - 10 * $i);
|
||||
$migration->status = 'Pending';
|
||||
$migration->Save();
|
||||
}
|
||||
}
|
||||
|
||||
protected function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
$migration = new Migration();
|
||||
$migration->DB()->execute("delete from Migrations");
|
||||
}
|
||||
|
||||
public function testGetCurrentMigrations()
|
||||
{
|
||||
$migrations = $this->migrationManager->getCurrentMigrations();
|
||||
self::assertEquals(5, count($migrations));
|
||||
}
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="name-of-project" default="build">
|
||||
<!-- By default, we assume all tools to be on the $PATH -->
|
||||
<property name="toolsdir" value=""/>
|
||||
|
||||
<!-- Uncomment the following when the tools are in ${basedir}/vendor/bin -->
|
||||
<!-- <property name="toolsdir" value="${basedir}/vendor/bin/"/> -->
|
||||
|
||||
<target name="build"
|
||||
depends="prepare,lint,phploc-ci,pdepend,phpmd-ci,phpcs-ci,phpcpd-ci,phpunit,phpdox"
|
||||
description=""/>
|
||||
|
||||
<target name="build-parallel"
|
||||
depends="prepare,lint,tools-parallel,phpunit,phpdox"
|
||||
description=""/>
|
||||
|
||||
<target name="tools-parallel" description="Run tools in parallel">
|
||||
<parallel threadCount="2">
|
||||
<sequential>
|
||||
<antcall target="pdepend"/>
|
||||
<antcall target="phpmd-ci"/>
|
||||
</sequential>
|
||||
<antcall target="phpcpd-ci"/>
|
||||
<antcall target="phpcs-ci"/>
|
||||
<antcall target="phploc-ci"/>
|
||||
</parallel>
|
||||
</target>
|
||||
|
||||
<target name="clean"
|
||||
unless="clean.done"
|
||||
description="Cleanup build artifacts">
|
||||
<delete dir="${basedir}/build/api"/>
|
||||
<delete dir="${basedir}/build/coverage"/>
|
||||
<delete dir="${basedir}/build/logs"/>
|
||||
<delete dir="${basedir}/build/pdepend"/>
|
||||
<delete dir="${basedir}/build/phpdox"/>
|
||||
<property name="clean.done" value="true"/>
|
||||
</target>
|
||||
|
||||
<target name="prepare"
|
||||
unless="prepare.done"
|
||||
depends="clean"
|
||||
description="Prepare for build">
|
||||
<mkdir dir="${basedir}/build/api"/>
|
||||
<mkdir dir="${basedir}/build/coverage"/>
|
||||
<mkdir dir="${basedir}/build/logs"/>
|
||||
<mkdir dir="${basedir}/build/pdepend"/>
|
||||
<mkdir dir="${basedir}/build/phpdox"/>
|
||||
<property name="prepare.done" value="true"/>
|
||||
</target>
|
||||
|
||||
<target name="lint" description="Perform syntax check of sourcecode files">
|
||||
<apply executable="php" failonerror="true">
|
||||
<arg value="-l" />
|
||||
|
||||
<fileset dir="${basedir}/src">
|
||||
<include name="**/*.php" />
|
||||
<modified />
|
||||
</fileset>
|
||||
|
||||
<fileset dir="${basedir}/tests">
|
||||
<include name="**/*.php" />
|
||||
<modified />
|
||||
</fileset>
|
||||
</apply>
|
||||
</target>
|
||||
|
||||
<target name="phploc"
|
||||
description="Measure project size using PHPLOC and print human readable output. Intended for usage on the command line.">
|
||||
<exec executable="${toolsdir}phploc">
|
||||
<arg value="--count-tests" />
|
||||
<arg path="${basedir}/src" />
|
||||
<arg path="${basedir}/tests" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phploc-ci"
|
||||
depends="prepare"
|
||||
description="Measure project size using PHPLOC and log result in CSV and XML format. Intended for usage within a continuous integration environment.">
|
||||
<exec executable="${toolsdir}phploc">
|
||||
<arg value="--count-tests" />
|
||||
<arg value="--log-csv" />
|
||||
<arg path="${basedir}/build/logs/phploc.csv" />
|
||||
<arg value="--log-xml" />
|
||||
<arg path="${basedir}/build/logs/phploc.xml" />
|
||||
<arg path="${basedir}/src" />
|
||||
<arg path="${basedir}/tests" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="pdepend"
|
||||
depends="prepare"
|
||||
description="Calculate software metrics using PHP_Depend and log result in XML format. Intended for usage within a continuous integration environment.">
|
||||
<exec executable="${toolsdir}pdepend">
|
||||
<arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml" />
|
||||
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" />
|
||||
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpmd"
|
||||
description="Perform project mess detection using PHPMD and print human readable output. Intended for usage on the command line before committing.">
|
||||
<exec executable="${toolsdir}phpmd">
|
||||
<arg path="${basedir}/src" />
|
||||
<arg value="text" />
|
||||
<arg path="${basedir}/build/phpmd.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpmd-ci"
|
||||
depends="prepare"
|
||||
description="Perform project mess detection using PHPMD and log result in XML format. Intended for usage within a continuous integration environment.">
|
||||
<exec executable="${toolsdir}phpmd">
|
||||
<arg path="${basedir}/src" />
|
||||
<arg value="xml" />
|
||||
<arg path="${basedir}/build/phpmd.xml" />
|
||||
<arg value="--reportfile" />
|
||||
<arg path="${basedir}/build/logs/pmd.xml" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpcs"
|
||||
description="Find coding standard violations using PHP_CodeSniffer and print human readable output. Intended for usage on the command line before committing.">
|
||||
<exec executable="${toolsdir}phpcs">
|
||||
<arg value="--standard=PSR2" />
|
||||
<arg value="--extensions=php" />
|
||||
<arg value="--ignore=autoload.php" />
|
||||
<arg path="${basedir}/src" />
|
||||
<arg path="${basedir}/tests" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpcs-ci"
|
||||
depends="prepare"
|
||||
description="Find coding standard violations using PHP_CodeSniffer and log result in XML format. Intended for usage within a continuous integration environment.">
|
||||
<exec executable="${toolsdir}phpcs" output="/dev/null">
|
||||
<arg value="--report=checkstyle" />
|
||||
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
|
||||
<arg value="--standard=PSR2" />
|
||||
<arg value="--extensions=php" />
|
||||
<arg value="--ignore=autoload.php" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpcpd"
|
||||
description="Find duplicate code using PHPCPD and print human readable output. Intended for usage on the command line before committing.">
|
||||
<exec executable="${toolsdir}phpcpd">
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpcpd-ci"
|
||||
depends="prepare"
|
||||
description="Find duplicate code using PHPCPD and log result in XML format. Intended for usage within a continuous integration environment.">
|
||||
<exec executable="${toolsdir}phpcpd">
|
||||
<arg value="--log-pmd" />
|
||||
<arg path="${basedir}/build/logs/pmd-cpd.xml" />
|
||||
<arg path="${basedir}/src" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpunit"
|
||||
depends="prepare"
|
||||
description="Run unit tests with PHPUnit">
|
||||
<exec executable="${toolsdir}phpunit" failonerror="true">
|
||||
<arg value="--configuration"/>
|
||||
<arg path="${basedir}/build/phpunit.xml"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="phpdox"
|
||||
depends="phploc-ci,phpcs-ci,phpmd-ci"
|
||||
description="Generate project documentation using phpDox">
|
||||
<exec executable="${toolsdir}phpdox" dir="${basedir}/build"/>
|
||||
</target>
|
||||
</project>
|
||||
|
||||
@@ -14,12 +14,12 @@ define('CLIENT_NAME', 'app');
|
||||
if (!defined('MYSQL_ROOT_USER') || !defined('MYSQL_ROOT_PASS')) {
|
||||
//Tests running on vagrant
|
||||
define('APP_BASE_PATH', TEST_BASE_PATH.'../core/');
|
||||
define('CLIENT_BASE_PATH', TEST_BASE_PATH.'../../deployment/clients/test/');
|
||||
define('BASE_URL', 'http://app.app.dev/');
|
||||
define('CLIENT_BASE_URL', 'http://clients.app.dev/dev/');
|
||||
define('CLIENT_BASE_PATH', TEST_BASE_PATH.'../deployment/clients/test/');
|
||||
define('BASE_URL', 'http://app.app.test/');
|
||||
define('CLIENT_BASE_URL', 'http://clients.app.test/dev/');
|
||||
} else {
|
||||
//Tests running on deploy
|
||||
define('APP_BASE_PATH', realpath(dirname(__FILE__).'/../app')."/core/");
|
||||
define('APP_BASE_PATH', realpath(dirname(__FILE__).'/../app/core')."/");
|
||||
define('CLIENT_BASE_PATH', APP_BASE_PATH.'');
|
||||
define('BASE_URL', 'http://apps.gamonoid.com/icehrmcore/');
|
||||
define('CLIENT_BASE_URL', 'http://apps.gamonoid.com/icehrm/');
|
||||
|
||||
@@ -34,5 +34,6 @@ if (!class_exists('SessionUtils')) {
|
||||
if (!class_exists('TestTemplate')) {
|
||||
include(dirname(__FILE__).'/TestTemplate.php');
|
||||
include(dirname(__FILE__).'/helper/EmployeeTestDataHelper.php');
|
||||
include(APP_BASE_PATH."includes.inc.php");
|
||||
include(APP_BASE_PATH."include.common.php");
|
||||
include(APP_BASE_PATH."server.includes.inc.php");
|
||||
}
|
||||
|
||||
24
test/unit/CalenderToolsUnit.php
Normal file
24
test/unit/CalenderToolsUnit.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
namespace Test\Unit;
|
||||
|
||||
use Utils\CalendarTools;
|
||||
|
||||
class CalenderToolsUnit extends \TestTemplate
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testGetYearFromDate()
|
||||
{
|
||||
$date = '2019-08-12';
|
||||
self::assertEquals('2019', CalendarTools::getYearFromDate($date));
|
||||
}
|
||||
|
||||
public function testAssignYearToDate()
|
||||
{
|
||||
$date = '2019-08-12';
|
||||
self::assertEquals('2017-08-12', CalendarTools::assignYearToDate($date, 2017));
|
||||
}
|
||||
}
|
||||
21
test/unit/EmployeeUtilUnit.php
Normal file
21
test/unit/EmployeeUtilUnit.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Test\Unit;
|
||||
|
||||
use Employees\Admin\Api\EmployeeUtil;
|
||||
|
||||
class EmployeeUtilUnit extends \TestTemplate
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testMapping()
|
||||
{
|
||||
$emplyeeUtils = new EmployeeUtil();
|
||||
$data = json_decode($emplyeeUtils->getMapping(), true);
|
||||
|
||||
$this->assertEquals($data['nationality'][0], 'Nationality');
|
||||
}
|
||||
}
|
||||
31
test/unit/EvalMathUnit.php
Normal file
31
test/unit/EvalMathUnit.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Test\Unit;
|
||||
|
||||
use Utils\Math\EvalMath;
|
||||
|
||||
class EvalMathUnit extends \TestTemplate
|
||||
{
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testTran()
|
||||
{
|
||||
$m = new EvalMath();
|
||||
// basic evaluation:
|
||||
$result = $m->evaluate('2+2');
|
||||
self::assertEquals(4, $result);
|
||||
// supports: order of operation; parentheses; negation; built-in functions
|
||||
$result = $m->evaluate('-8(5/2)^2*(1-sqrt(4))-8');
|
||||
self::assertEquals(42, $result);
|
||||
// create your own variables
|
||||
$m->evaluate('a = e^(ln(pi))');
|
||||
// or functions
|
||||
$m->evaluate('f(x,y) = x^2 + y^2 - 2x*y + 1');
|
||||
// and then use them
|
||||
$result = $m->evaluate('3*f(42,a)');
|
||||
self::assertEquals(4533, round($result));
|
||||
}
|
||||
}
|
||||
45
test/unit/PasswordManagerUnit.php
Normal file
45
test/unit/PasswordManagerUnit.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Test\Unit;
|
||||
|
||||
use Classes\PasswordManager;
|
||||
|
||||
class PasswordManagerUnit extends \TestTemplate
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
public function testVerifyCorrectPasswordBCrypt()
|
||||
{
|
||||
$password = 'tester-password327Red';
|
||||
$hash = PasswordManager::createPasswordHash($password);
|
||||
$this->assertTrue(PasswordManager::verifyPassword($password, $hash));
|
||||
}
|
||||
|
||||
public function testVerifyWrongPasswordBCrypt()
|
||||
{
|
||||
$password = 'tester-password327Red';
|
||||
$hash = PasswordManager::createPasswordHash($password);
|
||||
$this->assertFalse(PasswordManager::verifyPassword($password.'W', $hash));
|
||||
}
|
||||
|
||||
public function testVerifyCorrectPasswordMD5()
|
||||
{
|
||||
$hash = '21232f297a57a5a743894a0e4a801fc3';
|
||||
$this->assertTrue(PasswordManager::verifyPassword('admin', $hash));
|
||||
|
||||
$hash = '4048bb914a704a0728549a26b92d8550';
|
||||
$this->assertTrue(PasswordManager::verifyPassword('demouserpwd', $hash));
|
||||
}
|
||||
|
||||
public function testVerifyWrongPasswordMD5()
|
||||
{
|
||||
$hash = '21232f297a57a5a743894a0e4a801fc4';
|
||||
$this->assertFalse(PasswordManager::verifyPassword('admin', $hash));
|
||||
|
||||
$hash = '4048bb914a704a0728549a26b92d8550';
|
||||
$this->assertFalse(PasswordManager::verifyPassword('demouserpwd1', $hash));
|
||||
}
|
||||
}
|
||||
146
test/unit/ScriptRunnerUnit.php
Normal file
146
test/unit/ScriptRunnerUnit.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
namespace Test\Unit;
|
||||
|
||||
use Utils\ScriptRunner;
|
||||
|
||||
class ScriptRunnerUnit extends \TestTemplate
|
||||
{
|
||||
protected function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
public function testBasicSafeScript()
|
||||
{
|
||||
$script = <<<JS
|
||||
function main(k) {
|
||||
return k + Math.max(a, b);
|
||||
}
|
||||
const c = a * 8 + b;
|
||||
main(c);
|
||||
JS;
|
||||
$this->assertEquals(264, ScriptRunner::executeJs(['a' => 8, 'b' => 100], $script));
|
||||
}
|
||||
/*
|
||||
public function testScriptWithLongExecutionTime()
|
||||
{
|
||||
$script = <<<JS
|
||||
let c = a * 8 + b;
|
||||
let n = 0;
|
||||
while(n < 10000) {
|
||||
console.log(new Date().getTime());
|
||||
n++;
|
||||
}
|
||||
(c + Math.max(a, b));
|
||||
JS;
|
||||
$this->assertEquals(264, ScriptRunner::executeJs(['a' => 8, 'b' => 100], $script));
|
||||
}
|
||||
|
||||
public function testNeverEndingScript()
|
||||
{
|
||||
$script = <<<JS
|
||||
let c = a * 8 + b;
|
||||
while(1) {
|
||||
console.log(new Date().getTime());
|
||||
}
|
||||
(c + Math.max(a, b));
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs(['a' => 8, 'b' => 100], $script));
|
||||
}
|
||||
|
||||
public function testScriptWithRequire()
|
||||
{
|
||||
$script = <<<JS
|
||||
const fs = require('fs');
|
||||
let c = a * 8 + b;
|
||||
let n = 0;
|
||||
while(n < 10000) {
|
||||
console.log(new Date().getTime());
|
||||
n++;
|
||||
}
|
||||
(c + Math.max(a, b));
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs(['a' => 8, 'b' => 100], $script));
|
||||
}
|
||||
|
||||
public function testAccessFileSystem1()
|
||||
{
|
||||
$script = <<<JS
|
||||
__dirname
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs([], $script));
|
||||
}
|
||||
|
||||
public function testAccessFileSystem2()
|
||||
{
|
||||
$script = <<<JS
|
||||
const fs = module.constructor._load('fs');
|
||||
console.log(fs.readFileSync('./test.txt'));
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs([], $script));
|
||||
}
|
||||
|
||||
public function testAccessProcess()
|
||||
{
|
||||
$script = <<<JS
|
||||
process.exit(22);
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs([], $script));
|
||||
}
|
||||
|
||||
public function testScriptWithImport()
|
||||
{
|
||||
$script = <<<JS
|
||||
import { readFileSync } from 'fs'
|
||||
let c = a * 8 + b;
|
||||
(c + Math.max(a, b));
|
||||
JS;
|
||||
$this->assertEquals('', ScriptRunner::executeJs(['a' => 8, 'b' => 100], $script));
|
||||
}
|
||||
|
||||
public function testDoNotWaitForPromisesToResolve()
|
||||
{
|
||||
$script = <<<JS
|
||||
function test(){
|
||||
let k = new Promise((resolve, reject) => { resolve(val) });
|
||||
let n = 0;
|
||||
while (n < 2) {
|
||||
k = k.then((val) => new Promise((resolve, reject) => { resolve(val + 1); }));
|
||||
n ++;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await test();
|
||||
}
|
||||
main();
|
||||
val;
|
||||
JS;
|
||||
$res = ScriptRunner::executeJs(['val' => 100], $script);
|
||||
|
||||
$this->assertEquals(100, $res);
|
||||
}
|
||||
|
||||
public function testNeverEndingPromiseChain()
|
||||
{
|
||||
$script = <<<JS
|
||||
function test(){
|
||||
let k = new Promise((resolve, reject) => { resolve(val) });
|
||||
while (1) {
|
||||
k = k.then((val) => new Promise((resolve, reject) => { resolve(val + 1); }));
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
await test();
|
||||
}
|
||||
main();
|
||||
val;
|
||||
JS;
|
||||
$res = ScriptRunner::executeJs(['val' => 100], $script);
|
||||
|
||||
$this->assertEquals('', $res);
|
||||
}
|
||||
*/
|
||||
}
|
||||
14
test/web/api-common.js
Normal file
14
test/web/api-common.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const {
|
||||
RequestCache,
|
||||
setupTimeUtils,
|
||||
setupNotifications,
|
||||
} = require('../../web/api-common/bundle');
|
||||
|
||||
const bundle = require('../../web/api-common/bundle');
|
||||
const RequestCache1 = require('../../web/api-common/bundle').RequestCache;
|
||||
|
||||
const assert = require('assert');
|
||||
console.log('Test Started .....');
|
||||
console.log('Form Validation .....');
|
||||
let rc = new RequestCache();
|
||||
|
||||
Reference in New Issue
Block a user