feat(ui): introduce unit test (#263)

This commit is contained in:
Ludovic DEHON
2021-01-07 07:56:57 +01:00
committed by tchiotludo
parent a7a9aeff46
commit 20a5e7e3f5
14 changed files with 5052 additions and 584 deletions

1
.gitignore vendored
View File

@@ -31,6 +31,7 @@ ui/.env.local
ui/.env.*.local
webserver/src/main/resources/ui
yarn.lock
ui/coverage
### Docker
/.env

47
ui/.eslintrc.json Normal file
View File

@@ -0,0 +1,47 @@
{
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/strongly-recommended",
"eslint:recommended"
],
"rules": {
"vue/html-indent": [
"error",
4,
{
"baseIndent": 1
}
],
"vue/script-indent": [
"error",
4,
{
"baseIndent": 1
}
],
"vue/max-attributes-per-line": [
"error",
{
"singleline": 7
}
],
"quotes": [
"error",
"double"
],
"vue/object-curly-spacing": [
"error",
"never"
],
"object-curly-spacing": [
"error",
"never"
]
},
"parserOptions": {
"parser": "babel-eslint"
}
}

View File

@@ -7,7 +7,7 @@ bintrayUpload.enabled = false
frontend {
nodeVersion = '14.8.0'
assembleScript = 'run build'
checkScript = 'run test'
checkScript = 'run test:unit'
}
tasks.named('installFrontend') {

22
ui/jest.config.js Normal file
View File

@@ -0,0 +1,22 @@
module.exports = {
preset: "@vue/cli-plugin-unit-jest",
moduleFileExtensions: [
"js",
"json",
"vue"
],
transform: {
".*\\.(vue)$": "vue-jest",
".*\\.(js)$": "babel-jest"
},
transformIgnorePatterns: [
"/node_modules/(?!vue-material-design-icons)"
],
moduleNameMapper: {
"^.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$": "jest-transform-stub"
},
globals: {
"KESTRA_BASE_PATH": "/"
},
setupFiles: ["./tests/jest.setup.js"],
}

4488
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,10 +5,11 @@
"scripts": {
"serve": "vue-cli-service serve --port 8090",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.19.2",
"axios": "^0.21.1",
"bootstrap": "^4.5.3",
"bootstrap-vue": "^2.18.1",
"chart.js": "^2.9.4",
@@ -52,68 +53,35 @@
"vuex": "^3.5.1"
},
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@vue/cli-plugin-babel": "^4.5.8",
"@vue/cli-plugin-eslint": "^4.5.8",
"@vue/cli-plugin-unit-jest": "^4.4.4",
"@vue/cli-service": "^4.5.8",
"@vue/test-utils": "^1.1.2",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.3",
"eslint": "^7.11.0",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-vue": "^6.2.2",
"jest-transform-stub": "^2.0.0",
"node-sass": "^4.14.1",
"sass-loader": "^9.0.3",
"vue-jest": "^3.0.7",
"vue-template-compiler": "^2.6.12"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/strongly-recommended",
"eslint:recommended"
],
"rules": {
"vue/html-indent": [
"error",
4,
{
"baseIndent": 1
}
],
"vue/script-indent": [
"error",
4,
{
"baseIndent": 1
}
],
"vue/max-attributes-per-line": [
"error",
{
"singleline": 7
}
],
"quotes": [
"error",
"double"
],
"vue/object-curly-spacing": [
"error",
"never"
],
"object-curly-spacing": [
"error",
"never"
]
},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"babel": {
"presets": [
"@babel/preset-env"
]
},
"browserslist": [
"> 1%",
"last 2 versions"

View File

@@ -122,6 +122,7 @@
import LogLevelSelector from "../../components/logs/LogLevelSelector";
import SearchField from "../layout/SearchField";
import TaskIcon from "../plugins/TaskIcon";
import Kicon from "../Kicon"
export default {
components: {
@@ -135,6 +136,7 @@
LogLevelSelector,
SearchField,
TaskIcon,
Kicon
},
props: {
n: {
@@ -219,9 +221,9 @@
return this.taskRuns[0].state.current
}
const allStates = [...new Set(this.taskRuns.map(t => t.state.current))];
const allStates = this.taskRuns.map(t => t.state.current);
const sortStatus = [
const SORT_STATUS = [
State.FAILED,
State.KILLED,
State.WARNING,
@@ -232,11 +234,17 @@
State.SUCCESS
];
allStates.sort((a, b) => {
return sortStatus.indexOf(a[1]) - sortStatus.indexOf(b[1]);
});
// sorting based on SORT_STATUS array
const result = allStates
.map((item) => {
const n = SORT_STATUS.indexOf(item[1]);
SORT_STATUS[n] = undefined;
return [n, item]
})
.sort()
.map((j) => j[1])
return allStates[0];
return result[0];
},
duration() {
return this.taskRuns ? this.taskRuns.reduce((inc, taskRun) => inc + taskRun.state.duration, 0) : null;

View File

@@ -1,127 +1,127 @@
import _mapValues from "lodash/mapValues";
import _map from "lodash/map";
export default class State {
static States = Object.freeze({
CREATED: {
name: "CREATED",
colorClass: "info",
color: "#75bcdd",
icon: "pause-circle-outline",
isRunning: true,
isKillable: true
},
RESTARTED: {
name: "RESTARTED",
colorClass: "info",
color: "#75bcdd",
icon: "restart",
isRunning: false,
isKillable: true
},
SUCCESS: {
name: "SUCCESS",
colorClass: "success",
color: "#43ac6a",
icon: "check-circle-outline",
isRunning: false,
isKillable: false
},
RUNNING: {
name: "RUNNING",
colorClass: "primary",
color: "#1AA5DE",
icon: "play-circle-outline",
isRunning: true,
isKillable: true
},
KILLING: {
name: "KILLING",
colorClass: "warning",
color: "#FBD10B",
icon: "close-circle-outline",
isRunning: true,
isKillable: false
},
KILLED: {
name: "KILLED",
colorClass: "warning",
color: "#FBD10B",
icon: "stop-circle-outline",
isRunning: false,
isKillable: false
},
WARNING: {
name: "WARNING",
colorClass: "warning",
color: "#FBD10B",
icon: "alert-circle",
isRunning: false,
isKillable: false
},
FAILED: {
name: "FAILED",
colorClass: "danger",
color: "#F04124",
icon: "close-circle-outline",
isRunning: false,
isKillable: false
}
});
const STATE = Object.freeze({
CREATED: {
name: "CREATED",
colorClass: "info",
color: "#75bcdd",
icon: "pause-circle-outline",
isRunning: true,
isKillable: true
},
RESTARTED: {
name: "RESTARTED",
colorClass: "info",
color: "#75bcdd",
icon: "restart",
isRunning: false,
isKillable: true
},
SUCCESS: {
name: "SUCCESS",
colorClass: "success",
color: "#43ac6a",
icon: "check-circle-outline",
isRunning: false,
isKillable: false
},
RUNNING: {
name: "RUNNING",
colorClass: "primary",
color: "#1AA5DE",
icon: "play-circle-outline",
isRunning: true,
isKillable: true
},
KILLING: {
name: "KILLING",
colorClass: "warning",
color: "#FBD10B",
icon: "close-circle-outline",
isRunning: true,
isKillable: false
},
KILLED: {
name: "KILLED",
colorClass: "warning",
color: "#FBD10B",
icon: "stop-circle-outline",
isRunning: false,
isKillable: false
},
WARNING: {
name: "WARNING",
colorClass: "warning",
color: "#FBD10B",
icon: "alert-circle",
isRunning: false,
isKillable: false
},
FAILED: {
name: "FAILED",
colorClass: "danger",
color: "#F04124",
icon: "close-circle-outline",
isRunning: false,
isKillable: false
}
});
export default class State {
static get CREATED() {
return this.States.CREATED.name;
return STATE.CREATED.name;
}
static get RESTARTED() {
return this.States.RESTARTED.name;
return STATE.RESTARTED.name;
}
static get SUCCESS() {
return this.States.SUCCESS.name;
return STATE.SUCCESS.name;
}
static get RUNNING() {
return this.States.RUNNING.name;
return STATE.RUNNING.name;
}
static get KILLING() {
return this.States.KILLING.name;
return STATE.KILLING.name;
}
static get KILLED() {
return this.States.KILLED.name;
return STATE.KILLED.name;
}
static get FAILED() {
return this.States.FAILED.name;
return STATE.FAILED.name;
}
static get WARNING() {
return this.States.WARNING.name;
return STATE.WARNING.name;
}
static isRunning(state) {
return this.States[state] && this.States[state].isRunning;
return state[state] && state[state].isRunning;
}
static isKillable(state) {
return this.States[state] && this.States[state].isKillable;
return state[state] && state[state].isKillable;
}
static allStates() {
return _map(this.States, "name");
return _map(STATE, "name");
}
static colorClass() {
return _mapValues(this.States, state => state.colorClass);
return _mapValues(STATE, state => state.colorClass);
}
static color() {
return _mapValues(this.States, state => state.color);
return _mapValues(STATE, state => state.color);
}
static icon() {
return _mapValues(this.States, state => state.icon);
return _mapValues(STATE, state => state.icon);
}
}

8
ui/tests/.eslintrc.json Normal file
View File

@@ -0,0 +1,8 @@
{
"plugins": [
"jest"
],
"extends": [
"plugin:jest/recommended"
]
}

View File

@@ -0,0 +1,571 @@
{
"id": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"flowRevision": 1,
"taskRunList": [
{
"id": "5I8wRMwFnRvemjsGoHNpgU",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1_each",
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:11.815052Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:12.080549Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:16.466710Z"
}
],
"duration": 4.651658000,
"endDate": "2020-12-26T20:38:16.466710Z",
"startDate": "2020-12-26T20:38:11.815052Z"
}
},
{
"id": "p9zejsXPuEgCWtx75LSU3",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-1",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 1",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.018346625
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:12.783467Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:12.783474Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:12.808638Z"
}
],
"duration": 0.025171000,
"endDate": "2020-12-26T20:38:12.808638Z",
"startDate": "2020-12-26T20:38:12.783467Z"
}
}
],
"outputs": {
"value": "1-1 > value 1 > 2020-12-26T20:38:12.579069Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:12.579069Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:12.779722Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:12.822334Z"
}
],
"duration": 0.243265000,
"endDate": "2020-12-26T20:38:12.822334Z",
"startDate": "2020-12-26T20:38:12.579069Z"
}
},
{
"id": "74gCAfLKHu4a9EXqL7DzAx",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-2",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 1",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.004816050
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:13.493176Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:13.493179Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:13.499125Z"
}
],
"duration": 0.005949000,
"endDate": "2020-12-26T20:38:13.499125Z",
"startDate": "2020-12-26T20:38:13.493176Z"
}
}
],
"outputs": {
"value": "1-2 > value 1 > 2020-12-26T20:38:13.292869Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:13.292869Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:13.490853Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:13.505448Z"
}
],
"duration": 0.212579000,
"endDate": "2020-12-26T20:38:13.505448Z",
"startDate": "2020-12-26T20:38:13.292869Z"
}
},
{
"id": "4MuXCa5VCkkWXxRO9BOXwk",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-1",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 2",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.004785041
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:14.066144Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:14.066149Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:14.072785Z"
}
],
"duration": 0.006641000,
"endDate": "2020-12-26T20:38:14.072785Z",
"startDate": "2020-12-26T20:38:14.066144Z"
}
}
],
"outputs": {
"value": "1-1 > value 2 > 2020-12-26T20:38:13.861179Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:13.861179Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:14.063946Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:14.080290Z"
}
],
"duration": 0.219111000,
"endDate": "2020-12-26T20:38:14.080290Z",
"startDate": "2020-12-26T20:38:13.861179Z"
}
},
{
"id": "5706Z8X2BI1ZRrEkuEFPen",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-2",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 2",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.003328988
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:14.743453Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:14.743458Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:14.747653Z"
}
],
"duration": 0.004200000,
"endDate": "2020-12-26T20:38:14.747653Z",
"startDate": "2020-12-26T20:38:14.743453Z"
}
}
],
"outputs": {
"value": "1-2 > value 2 > 2020-12-26T20:38:14.548231Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:14.548231Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:14.740714Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:14.752540Z"
}
],
"duration": 0.204309000,
"endDate": "2020-12-26T20:38:14.752540Z",
"startDate": "2020-12-26T20:38:14.548231Z"
}
},
{
"id": "3JryMXDuJArQhj8uFmqkRD",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-1",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 3",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.008318245
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:15.305015Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:15.305019Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:15.314287Z"
}
],
"duration": 0.009272000,
"endDate": "2020-12-26T20:38:15.314287Z",
"startDate": "2020-12-26T20:38:15.305015Z"
}
}
],
"outputs": {
"value": "1-1 > value 3 > 2020-12-26T20:38:15.111933Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:15.111933Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:15.301952Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:15.320734Z"
}
],
"duration": 0.208801000,
"endDate": "2020-12-26T20:38:15.320734Z",
"startDate": "2020-12-26T20:38:15.111933Z"
}
},
{
"id": "68GkiSkymFFcFXsopKydNF",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "1-2",
"parentTaskRunId": "5I8wRMwFnRvemjsGoHNpgU",
"value": "value 3",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"value": 43.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.004866406
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:15.991107Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:15.991112Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:15.996888Z"
}
],
"duration": 0.005781000,
"endDate": "2020-12-26T20:38:15.996888Z",
"startDate": "2020-12-26T20:38:15.991107Z"
}
}
],
"outputs": {
"value": "1-2 > value 3 > 2020-12-26T20:38:15.785083Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:15.785083Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:15.988104Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:16.002047Z"
}
],
"duration": 0.216964000,
"endDate": "2020-12-26T20:38:16.002047Z",
"startDate": "2020-12-26T20:38:15.785083Z"
}
},
{
"id": "4vkpV3Bn4Wjd2l6SvWKm79",
"executionId": "20CzMipsC3DZvcDOWqkST",
"namespace": "org.kestra.tests",
"flowId": "each-sequential",
"taskId": "2_end",
"attempts": [
{
"metrics": [
{
"name": "length",
"tags": {
"format": "{{task.id}} > {{taskrun.startDate}}"
},
"value": 35.0,
"type": "counter"
},
{
"name": "duration",
"tags": {
"format": "{{task.id}} > {{taskrun.startDate}}"
},
"type": "timer",
"value": 0.003764310
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:17.040143Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:17.040149Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:17.046017Z"
}
],
"duration": 0.005874000,
"endDate": "2020-12-26T20:38:17.046017Z",
"startDate": "2020-12-26T20:38:17.040143Z"
}
}
],
"outputs": {
"value": "2_end > 2020-12-26T20:38:16.845018Z"
},
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:16.845018Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:17.037510Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:17.051064Z"
}
],
"duration": 0.206046000,
"endDate": "2020-12-26T20:38:17.051064Z",
"startDate": "2020-12-26T20:38:16.845018Z"
}
}
],
"state": {
"current": "SUCCESS",
"histories": [
{
"state": "CREATED",
"date": "2020-12-26T20:38:11.496183Z"
},
{
"state": "RUNNING",
"date": "2020-12-26T20:38:11.823665Z"
},
{
"state": "SUCCESS",
"date": "2020-12-26T20:38:17.506625Z"
}
],
"duration": 6.010442000,
"endDate": "2020-12-26T20:38:17.506625Z",
"startDate": "2020-12-26T20:38:11.496183Z"
}
}

View File

@@ -0,0 +1,162 @@
{
"nodes": [
{
"uid": "iPEGVh8eo6L2eJvAZ7yZ7_root",
"type": "org.kestra.core.models.hierarchies.GraphClusterRoot"
},
{
"uid": "21OCHso6nuOEOy2f6LA1tu_end",
"type": "org.kestra.core.models.hierarchies.GraphClusterEnd"
},
{
"uid": "1_each_6PrKjf95xBLmWqrejmv8aH_root",
"type": "org.kestra.core.models.hierarchies.GraphClusterRoot",
"task": {
"id": "1_each",
"type": "org.kestra.core.tasks.flows.EachSequential",
"tasks": [
{
"id": "1-1",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
{
"id": "1-2",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
}
],
"value": "[\"value 1\", \"value 2\", \"value 3\"]"
},
"relationType": "DYNAMIC"
},
{
"uid": "1_each_4fwiMSrBsSia67rYJlnuuL_end",
"type": "org.kestra.core.models.hierarchies.GraphClusterEnd",
"task": {
"id": "1_each",
"type": "org.kestra.core.tasks.flows.EachSequential",
"tasks": [
{
"id": "1-1",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
{
"id": "1-2",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
}
],
"value": "[\"value 1\", \"value 2\", \"value 3\"]"
},
"relationType": "DYNAMIC"
},
{
"uid": "1-1",
"type": "org.kestra.core.models.hierarchies.GraphTask",
"task": {
"id": "1-1",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"relationType": "SEQUENTIAL"
},
{
"uid": "1-2",
"type": "org.kestra.core.models.hierarchies.GraphTask",
"task": {
"id": "1-2",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
"relationType": "SEQUENTIAL"
},
{
"uid": "2_end",
"type": "org.kestra.core.models.hierarchies.GraphTask",
"task": {
"id": "2_end",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.startDate}}"
},
"relationType": "SEQUENTIAL"
}
],
"edges": [
{
"source": "2_end",
"target": "21OCHso6nuOEOy2f6LA1tu_end",
"relation": {
}
},
{
"source": "1_each_4fwiMSrBsSia67rYJlnuuL_end",
"target": "2_end",
"relation": {
}
},
{
"source": "iPEGVh8eo6L2eJvAZ7yZ7_root",
"target": "1_each_6PrKjf95xBLmWqrejmv8aH_root",
"relation": {
}
},
{
"source": "1-2",
"target": "1_each_4fwiMSrBsSia67rYJlnuuL_end",
"relation": {
}
},
{
"source": "1-1",
"target": "1-2",
"relation": {
"relationType": "DYNAMIC"
}
},
{
"source": "1_each_6PrKjf95xBLmWqrejmv8aH_root",
"target": "1-1",
"relation": {
"relationType": "DYNAMIC"
}
}
],
"clusters": [
{
"cluster": {
"uid": "1_each",
"type": "org.kestra.core.models.hierarchies.GraphCluster",
"task": {
"id": "1_each",
"type": "org.kestra.core.tasks.flows.EachSequential",
"tasks": [
{
"id": "1-1",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
},
{
"id": "1-2",
"type": "org.kestra.core.tasks.debugs.Return",
"format": "{{task.id}} > {{taskrun.value}} > {{taskrun.startDate}}"
}
],
"value": "[\"value 1\", \"value 2\", \"value 3\"]"
},
"relationType": "DYNAMIC"
},
"nodes": [
"1_each_6PrKjf95xBLmWqrejmv8aH_root",
"1_each_4fwiMSrBsSia67rYJlnuuL_end",
"1-1",
"1-2"
]
}
]
}

15
ui/tests/jest.setup.js Normal file
View File

@@ -0,0 +1,15 @@
import {config} from "@vue/test-utils";
import "../src/filters"
String.prototype.hashCode = function () {
let hash = 0;
for (let i = 0; i < this.length; i++) {
let character = this.charCodeAt(i);
hash = ((hash << 5) - hash) + character;
hash = hash & hash;
}
return hash;
}
config.mocks.$t = key => key;

10
ui/tests/local.js Normal file
View File

@@ -0,0 +1,10 @@
import {createLocalVue} from "@vue/test-utils"
import BootstrapVue from "bootstrap-vue"
import Vuex from "vuex"
const localVue = createLocalVue()
localVue.use(BootstrapVue)
localVue.use(Vuex)
export default localVue

View File

@@ -0,0 +1,64 @@
import {shallowMount} from "@vue/test-utils";
import Vuex from "vuex"
import _ from "lodash";
import TreeNode from "../../../../src/components/graph/TreeNode.vue";
import EACH_SEQUENTIAL_FLOWGRAPH from "../../../fixtures/flowgraphs/each-sequential.json";
import EACH_SEQUENTIAL_EXECUTION from "../../../fixtures/executions/each-sequential.json";
import localVue from "../../../local.js";
const mount = (store, n, execution) => shallowMount(TreeNode, {
localVue,
store,
propsData: {
n: n,
execution: execution,
flowId: "flowId",
namespace: "namespace",
}
})
describe("TreeNode", () => {
let store
beforeEach(() => {
store = new Vuex.Store({
modules: {
plugin: {
state: {
icons: []
},
namespaced: true
}
}
})
})
it("success execution", () => {
const wrapper = mount(
store,
EACH_SEQUENTIAL_FLOWGRAPH.nodes.filter(r => r.uid === "1-2")[0],
EACH_SEQUENTIAL_EXECUTION,
)
expect(wrapper.vm.task.id).toBe("1-2");
expect(wrapper.vm.state).toBe("SUCCESS");
expect(wrapper.vm.taskRuns).toHaveLength(3);
expect(wrapper.vm.duration).toBe(0.633852);
})
it("sorting state", () => {
const taskRun = EACH_SEQUENTIAL_EXECUTION.taskRunList.filter(r => r.id === "68GkiSkymFFcFXsopKydNF")[0];
const taskRunIndex = EACH_SEQUENTIAL_EXECUTION.taskRunList.indexOf(taskRun);
const failed = _.clone(EACH_SEQUENTIAL_EXECUTION)
failed.taskRunList[taskRunIndex] = _.merge({taskId:"1-2", state: {current: "FAILED"}})
const wrapper = mount(
store,
EACH_SEQUENTIAL_FLOWGRAPH.nodes.filter(r => r.uid === "1-2")[0],
failed,
)
expect(wrapper.vm.state).toBe("FAILED");
})
})