More Fixes to policy checks

This commit is contained in:
Josh Krawczyk
2020-06-16 23:51:07 -04:00
parent ac9bb945e8
commit 5d9d84cd72
6 changed files with 237 additions and 67 deletions

View File

@@ -1,6 +1,5 @@
<template>
<div v-if="selectedPolicy === null">No Policy Selected</div>
<div class="row" v-else>
<div class="row">
<div class="col-12">
<q-btn
size="sm"
@@ -18,19 +17,16 @@
icon="refresh"
ref="refresh"
/>
<template v-if="tasks === undefined || tasks.length === 0">
<p>No Tasks</p>
</template>
<template v-else>
<template>
<q-table
dense
class="tabs-tbl-sticky"
:data="tasks"
:columns="columns"
:row-key="row => row.id"
row-key="id"
binary-state-sort
:pagination.sync="pagination"
hide-bottom
hide-pagination
>
<!-- header slots -->
<template v-slot:header-cell-enabled="props">
@@ -38,6 +34,17 @@
<small>Enabled</small>
</q-th>
</template>
<!-- No data Slot -->
<template v-slot:no-data >
<div class="full-width row flex-center q-gutter-sm">
<span v-if="selectedPolicy === null">
Click on a policy to see the tasks
</span>
<span v-else>
There are no tasks added to this policy
</span>
</div>
</template>
<!-- body slots -->
<template v-slot:body="props" :props="props">
<q-tr @contextmenu="editTaskPk = props.row.id">

View File

@@ -1,6 +1,5 @@
<template>
<div v-if="selectedPolicy === null">No Policy Selected</div>
<div class="row" v-else>
<div class="row">
<div class="col-12">
<q-btn
size="sm"
@@ -65,19 +64,16 @@
icon="refresh"
ref="refresh"
/>
<template v-if="checks.length === 0">
<p>No Checks</p>
</template>
<template v-else>
<template>
<q-table
dense
class="tabs-tbl-sticky"
:data="checks"
:columns="columns"
:row-key="row => row.id + row.check_type"
row-key="id"
binary-state-sort
:pagination.sync="pagination"
hide-bottom
hide-pagination
>
<!-- header slots -->
<template v-slot:header-cell-smsalert="props">
@@ -97,6 +93,17 @@
<template v-slot:header-cell-statusicon="props">
<q-th auto-width :props="props"></q-th>
</template>
<!-- No data Slot -->
<template v-slot:no-data >
<div class="full-width row flex-center q-gutter-sm">
<span v-if="selectedPolicy === null">
Click on a policy to see the checks
</span>
<span v-else>
There are no checks added to this policy
</span>
</div>
</template>
<!-- body slots -->
<template v-slot:body="props">
<q-tr :props="props">
@@ -162,7 +169,7 @@
v-model="props.row.email_alert"
/>
</q-td>
<q-td>{{ getDescription(props.row) }}</q-td>
<q-td>{{ props.row.readable_desc }}</q-td>
<q-td>
<span
style="cursor:pointer;color:blue;text-decoration:underline"
@@ -185,7 +192,6 @@
<PolicyStatus
type="check"
:item="statusCheck"
:description="getDescription(statusCheck)"
/>
</q-dialog>
@@ -311,6 +317,7 @@ export default {
hideDialog(component) {
this.showDialog = false;
this.dialogComponent = null;
this.editCheckPK = null;
},
deleteCheck(check) {
this.$q
@@ -336,22 +343,6 @@ export default {
closePolicyCheckStatusModal() {
this.showPolicyCheckStatus = false;
this.statusCheck = {};
},
getDescription(check) {
if (check.check_type === "diskspace")
return `Disk Space Drive ${check.disk} > ${check.threshold}%`;
else if (check.check_type === "cpuload")
return `Avg CPU Load > ${check.threshold}%`;
else if (check.check_type === "script")
return `Script check: ${check.script.name}`;
else if (check.check_type === "ping")
return `Ping ${check.name} (${check.ip})`;
else if (check.check_type === "memory")
return `Avg memory usage > ${check.threshold}%`;
else if (check.check_type === "winsvc")
return `Service Check - ${check.svc_display_name}`;
else if (check.check_type === "eventlog")
return `Event Log Check - ${check.name}`
}
},
computed: {

View File

@@ -1,7 +1,7 @@
<template>
<q-card style="width: 90vw" >
<q-card-section class="row items-center">
<div class="text-h6">{{ this.description }}</div>
<div class="text-h6">{{ this.item.readable_desc }}</div>
<q-space />
<q-btn icon="close" flat round dense v-close-popup />
</q-card-section>
@@ -14,12 +14,20 @@
row-key="id"
binary-state-sort
:pagination.sync="pagination"
hide-bottom
hide-pagination
>
<!-- header slots -->
<template v-slot:header-cell-statusicon="props">
<q-th auto-width :props="props"></q-th>
</template>
<!-- No data Slot -->
<template v-slot:no-data >
<div class="full-width row flex-center q-gutter-sm">
<span>
There are no agents applied to this policy
</span>
</div>
</template>
<!-- body slots -->
<template v-slot:body="props" :props="props">
<q-tr>
@@ -45,19 +53,22 @@
<q-td v-if="props.row.check_type === 'ping'">
<span
style="cursor:pointer;color:blue;text-decoration:underline"
@click="pingInfo(props.row.readable_desc, props.row.more_info)"
@click="pingInfo(props.row)"
class="ping-cell"
>output</span>
</q-td>
<q-td v-else-if="props.row.check_type === 'script'">
<span
style="cursor:pointer;color:blue;text-decoration:underline"
@click="scriptMoreInfo(props.row)"
class="script-cell"
>output</span>
</q-td>
<q-td v-else-if="props.row.check_type === 'eventlog'">
<span
style="cursor:pointer;color:blue;text-decoration:underline"
@click="eventLogMoreInfo(props.row)"
class="eventlog-cell"
>output</span>
</q-td>
<q-td
@@ -84,7 +95,6 @@
</template>
<script>
import { mapGetters } from "vuex";
import ScriptOutput from "@/components/modals/checks/ScriptOutput";
import EventLogCheckOutput from "@/components/modals/checks/EventLogCheckOutput";
@@ -106,9 +116,6 @@ export default {
// The value must match one of these strings
return ["task", "check"].includes(value);
}
},
description: {
type: String
}
},
data() {
@@ -175,20 +182,20 @@ export default {
this.showScriptOutput = false;
this.scriptInfo = {}
},
pingInfo(desc, output) {
pingInfo(check) {
this.$q.dialog({
title: desc,
title: check.readable_desc,
style: "width: 50vw; max-width: 60vw",
message: `<pre>${output}</pre>`,
message: `<pre>${check.more_info}</pre>`,
html: true
});
},
scriptMoreInfo(props) {
this.scriptInfo = props;
scriptMoreInfo(check) {
this.scriptInfo = check;
this.showScriptOutput = true;
},
eventLogMoreInfo(props) {
this.evtLogData = props;
eventLogMoreInfo(check) {
this.evtLogData = check;
this.showEventLogOutput = true;
},
},

View File

@@ -1,4 +1,4 @@
import { mount, shallowMount, createWrapper, createLocalVue } from "@vue/test-utils";
import { mount, createWrapper, createLocalVue } from "@vue/test-utils";
import PolicyChecksTab from "@/components/automation/PolicyChecksTab";
import Vuex from "vuex";
import "../../utils/quasar.js"
@@ -59,7 +59,7 @@ describe("PolicyChecksTab.vue with no policy selected", () => {
}
});
wrapper = shallowMount(PolicyChecksTab, {
wrapper = mount(PolicyChecksTab, {
store,
localVue
});
@@ -69,7 +69,7 @@ describe("PolicyChecksTab.vue with no policy selected", () => {
/*** TESTS ***/
it("renders text when policy is selected with no checks", () => {
expect(wrapper.html()).toContain("No Policy Selected");
expect(wrapper.html()).toContain("Click on a policy to see the checks");
});
});
@@ -140,7 +140,7 @@ describe("PolicyChecksTab.vue with policy selected and no checks", () => {
it("renders text when policy is selected with no checks", () => {
expect(wrapper.html()).toContain("No Checks");
expect(wrapper.html()).toContain("There are no checks added to this policy");
});
it("sends vuex actions on refresh button click", () => {
@@ -305,17 +305,6 @@ describe("PolicyChecksTab.vue with policy selected and checks", () => {
expect(wrapper.vm.statusCheck).toEqual(diskcheck);
});
it("renders correct description for checks", () => {
expect(wrapper.find(".q-table").html()).toContain("Disk Space Drive C: &gt; 25%");
expect(wrapper.find(".q-table").html()).toContain("Avg CPU Load &gt; 85%");
expect(wrapper.find(".q-table").html()).toContain("Avg memory usage &gt; 75%");
expect(wrapper.find(".q-table").html()).toContain("Script check: Test Script");
expect(wrapper.find(".q-table").html()).toContain("Service Check - Agent Activation Runtime_1232as");
expect(wrapper.find(".q-table").html()).toContain("Ping fghfgh (10.10.10.10)");
expect(wrapper.find(".q-table").html()).toContain("Event Log Check - asasasa");
});
it("deletes check", async () => {
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);

View File

@@ -0,0 +1,176 @@
import { mount, createWrapper, createLocalVue } from "@vue/test-utils";
import Vuex from "vuex";
import flushpromises from "flush-promises";
import PolicyStatus from "@/components/automation/modals/PolicyStatus";
import "../../utils/quasar.js";
const localVue = createLocalVue();
localVue.use(Vuex);
const bodyWrapper = createWrapper(document.body);
// This is needed to remove q-dialogs since body doesn't rerender
afterEach(() => {
const dialogs = document.querySelectorAll(".q-dialog");
const menus = document.querySelectorAll(".q-menu");
dialogs.forEach(x => x.remove());
menus.forEach(x => x.remove());
});
// test data
const item = {
id: 1,
readable_desc: "Check Description"
};
describe("PolicyStatus.vue viewing check status", () => {
const data = [
{
hostname: "Agent 1",
status: "pending",
check_type: "ping",
last_run: "Last Run"
},
{
hostname: "Agent 2",
status: "passing",
check_type: "script",
last_run: "Last Run"
},
{
hostname: "Agent 3",
status: "failing",
check_type: "eventlog",
last_run: "Last Run"
},
];
let wrapper, actions, store;
// Runs before every test
beforeEach(() => {
actions = {
loadCheckStatus: jest.fn(() => Promise.resolve({ data: data }))
};
store = new Vuex.Store({
modules: {
automation: {
namespaced: true,
actions,
}
}
});
wrapper = mount(PolicyStatus, {
localVue,
store,
propsData: {
item: item,
type: "check"
},
stubs: [
"ScriptOutput",
"EventLogCheckOutput"
]
});
});
it("calls correct check vuex action on mount", () => {
expect(actions.loadCheckStatus).toHaveBeenCalledWith(expect.anything(), { checkpk: item.id });
});
it("renders correct number of rows in table", async () => {
await flushpromises();
await localVue.nextTick();
const rows = wrapper.findAll(".q-table > tbody > .q-tr").wrappers;
expect(rows).toHaveLength(3);
});
it("shows event log status on cell click", async () => {
await flushpromises();
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
const row = wrapper.findAll(".eventlog-cell").wrappers[0];
await row.trigger("click");
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
// Needs to be equal to eventlog check in test data array
expect(wrapper.vm.evtLogData).toEqual(data[2]);
});
it("shows script status on cell click", async () => {
await flushpromises();
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
const row = wrapper.findAll(".script-cell").wrappers[0];
await row.trigger("click");
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
// Needs to be equal to script check in test data array
expect(wrapper.vm.scriptInfo).toEqual(data[1]);
});
it("shows pingstatus on cell click", async () => {
await flushpromises();
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
const row = wrapper.findAll(".ping-cell").wrappers[0];
await row.trigger("click");
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
});
});
describe("PolicyStatus.vue viewing task status", () => {
const data = [];
let wrapper, actions, store;
// Runs before every test
beforeEach(() => {
actions = {
loadAutomatedTaskStatus: jest.fn(() => Promise.resolve({ data: data })),
};
store = new Vuex.Store({
modules: {
automation: {
namespaced: true,
actions,
}
}
});
wrapper = mount(PolicyStatus, {
localVue,
store,
propsData: {
item: item,
type: "task"
},
stubs: [
"ScriptOutput",
"EventLogCheckOutput"
]
});
});
it("calls correct check vuex action on mount", () => {
expect(actions.loadAutomatedTaskStatus).toHaveBeenCalledWith(expect.anything(), { taskpk: item.id });
});
});

View File

@@ -1,4 +1,4 @@
import { mount, shallowMount, createWrapper, createLocalVue } from "@vue/test-utils";
import { mount, createWrapper, createLocalVue } from "@vue/test-utils";
import PolicyAutomatedTasksTab from "@/components/automation/PolicyAutomatedTasksTab";
import Vuex from "vuex";
import "../../utils/quasar.js";
@@ -53,7 +53,7 @@ describe("PolicyAutomatedTasksTab.vue with no policy selected", () => {
}
});
wrapper = shallowMount(PolicyAutomatedTasksTab, {
wrapper = mount(PolicyAutomatedTasksTab, {
store,
localVue
});
@@ -63,7 +63,7 @@ describe("PolicyAutomatedTasksTab.vue with no policy selected", () => {
/*** TESTS ***/
it("renders text when policy is selected with no tasks", () => {
expect(wrapper.html()).toContain("No Policy Selected");
expect(wrapper.html()).toContain("Click on a policy to see the tasks");
});
});
@@ -120,7 +120,7 @@ describe("PolicyAutomatedTasksTab.vue with policy selected and no tasks", () =>
it("renders text when policy is selected with no tasks", () => {
expect(wrapper.html()).toContain("No Tasks");
expect(wrapper.html()).toContain("There are no tasks added to this policy");
});
it("sends vuex actions on refresh button click", () => {