mirror of
https://github.com/jpros/tacticalrmm-web.git
synced 2026-03-01 07:41:00 +00:00
Merge pull request #12 from sadnub/feature-policies-alerts
Vue unit test start
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
module.exports = {
|
||||
preset: '@vue/cli-plugin-unit-jest'
|
||||
preset: '@vue/cli-plugin-unit-jest',
|
||||
moduleNameMapper: {
|
||||
quasar: "quasar/dist/quasar.umd.min.js"
|
||||
},
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<q-item-section>Script Manager</q-item-section>
|
||||
</q-item>
|
||||
<!-- automation manager -->
|
||||
<q-item clickable v-close-popup @click="showAutomationManager">
|
||||
<q-item clickable v-close-popup @click="showAutomationManager = true">
|
||||
<q-item-section>Automation Manager</q-item-section>
|
||||
</q-item>
|
||||
<!-- core settings -->
|
||||
@@ -90,7 +90,11 @@
|
||||
<ScriptManager />
|
||||
|
||||
<!-- Automation Manager -->
|
||||
<AutomationManager />
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
<q-dialog v-model="showAutomationManager">
|
||||
<AutomationManager @close="showAutomationManager = false"/>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</q-bar>
|
||||
</div>
|
||||
</template>
|
||||
@@ -127,7 +131,8 @@ export default {
|
||||
showAddSiteModal: false,
|
||||
showEditSitesModal: false,
|
||||
showUpdateAgentsModal: false,
|
||||
showEditCoreSettingsModal: false
|
||||
showEditCoreSettingsModal: false,
|
||||
showAutomationManager: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@@ -137,9 +142,6 @@ export default {
|
||||
showScriptManager() {
|
||||
this.$store.commit("TOGGLE_SCRIPT_MANAGER", true);
|
||||
},
|
||||
showAutomationManager() {
|
||||
this.$store.commit("TOGGLE_AUTOMATION_MANAGER", true);
|
||||
},
|
||||
edited() {
|
||||
this.$emit("edited");
|
||||
}
|
||||
|
||||
@@ -1,99 +1,107 @@
|
||||
<template>
|
||||
<div class="q-pa-md q-gutter-sm">
|
||||
<q-dialog :value="toggleAutomationManager" @hide="hideAutomationManager" @show="getPolicies">
|
||||
<q-card style="width: 900px; max-width: 90vw;">
|
||||
<q-bar>
|
||||
<q-btn @click="getPolicies" class="q-mr-sm" dense flat push icon="refresh" />Automation Manager
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<div class="q-pa-md">
|
||||
<div class="q-gutter-sm">
|
||||
<q-btn
|
||||
label="New"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="add"
|
||||
@click="showAddPolicyModal = true; clearRow"
|
||||
/>
|
||||
<q-btn
|
||||
label="Edit"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="edit"
|
||||
@click="showEditPolicyModal = true"
|
||||
/>
|
||||
<q-btn
|
||||
label="Delete"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="delete"
|
||||
@click="deletePolicy"
|
||||
/>
|
||||
<q-btn
|
||||
label="Policy Overview"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="remove_red_eye"
|
||||
@click="showPolicyOverviewModal = true"
|
||||
/>
|
||||
</div>
|
||||
<q-table
|
||||
<div style="width: 900px; max-width: 90vw;">
|
||||
<q-card>
|
||||
<q-bar>
|
||||
<q-btn ref="refresh" @click="getPolicies; clearRow()" class="q-mr-sm" dense flat push icon="refresh" />Automation Manager
|
||||
<q-space />
|
||||
<q-btn dense flat icon="close" v-close-popup>
|
||||
<q-tooltip content-class="bg-white text-primary">Close</q-tooltip>
|
||||
</q-btn>
|
||||
</q-bar>
|
||||
<div class="q-pa-md">
|
||||
<div class="q-gutter-sm">
|
||||
<q-btn
|
||||
ref="new"
|
||||
label="New"
|
||||
dense
|
||||
class="automation-sticky-header-table"
|
||||
:data="policies"
|
||||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
:pagination.sync="pagination"
|
||||
row-key="id"
|
||||
binary-state-sort
|
||||
hide-bottom
|
||||
virtual-scroll
|
||||
flat
|
||||
:rows-per-page-options="[0]"
|
||||
>
|
||||
<template slot="body" slot-scope="props" :props="props">
|
||||
<q-tr
|
||||
:class="{highlight: selectedRow === props.row.id}"
|
||||
@click="policyRowSelected(props.row.id)"
|
||||
>
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td>{{ props.row.desc }}</q-td>
|
||||
<q-td>{{ props.row.active }}</q-td>
|
||||
<q-td>{{ props.row.clients.length }}</q-td>
|
||||
<q-td>{{ props.row.sites.length }}</q-td>
|
||||
<q-td>{{ props.row.agents.length }}</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="add"
|
||||
@click="showPolicyFormModal = true; clearRow()"
|
||||
/>
|
||||
<q-btn
|
||||
ref="edit"
|
||||
label="Edit"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="edit"
|
||||
@click="showPolicyFormModal = true"
|
||||
/>
|
||||
<q-btn
|
||||
ref="delete"
|
||||
label="Delete"
|
||||
:disable="selectedRow === null"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="delete"
|
||||
@click="deletePolicy"
|
||||
/>
|
||||
<q-btn
|
||||
ref="overview"
|
||||
label="Policy Overview"
|
||||
dense
|
||||
flat
|
||||
push
|
||||
unelevated
|
||||
no-caps
|
||||
icon="remove_red_eye"
|
||||
@click="showPolicyOverviewModal = true"
|
||||
/>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<PolicySubTableTabs :policypk="policyPkSelected" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showAddPolicyModal">
|
||||
<AddPolicy @close="showAddPolicyModal = false" @added="getPolicies" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showEditPolicyModal">
|
||||
<EditPolicy :pk="selectedRow" @close="showEditPolicyModal = false" @edited="getPolicies" />
|
||||
<q-table
|
||||
dense
|
||||
class="automation-sticky-header-table"
|
||||
:data="policies"
|
||||
:columns="columns"
|
||||
:visible-columns="visibleColumns"
|
||||
:pagination.sync="pagination"
|
||||
:selected.sync="selected"
|
||||
@selection="policyRowSelected"
|
||||
selection="single"
|
||||
row-key="id"
|
||||
binary-state-sort
|
||||
hide-bottom
|
||||
flat
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
{{ col.label }}
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
<q-tr
|
||||
:props="props"
|
||||
class="cursor-pointer"
|
||||
@click="props.selected = true"
|
||||
>
|
||||
<q-td>{{ props.row.name }}</q-td>
|
||||
<q-td>{{ props.row.desc }}</q-td>
|
||||
<q-td>{{ props.row.active }}</q-td>
|
||||
<q-td>{{ props.row.clients.length }}</q-td>
|
||||
<q-td>{{ props.row.sites.length }}</q-td>
|
||||
<q-td>{{ props.row.agents.length }}</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
</div>
|
||||
|
||||
<q-card-section>
|
||||
<PolicySubTableTabs :policypk="selected.id" />
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
<q-dialog v-model="showPolicyFormModal">
|
||||
<PolicyForm @close="showPolicyFormModal = false" @refresh="getPolicies; clearRow()" />
|
||||
</q-dialog>
|
||||
<q-dialog v-model="showPolicyOverviewModal">
|
||||
<PolicyOverview @close="showPolicyOverviewModal = false" />
|
||||
@@ -102,24 +110,21 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import { mapState } from 'vuex';
|
||||
import AddPolicy from "@/components/automation/modals/AddPolicy";
|
||||
import EditPolicy from "@/components/automation/modals/EditPolicy";
|
||||
import PolicyForm from "@/components/automation/modals/PolicyForm";
|
||||
import PolicyOverview from "@/components/automation/PolicyOverview";
|
||||
import PolicySubTableTabs from "@/components/automation/PolicySubTableTabs"
|
||||
|
||||
export default {
|
||||
name: "AutomationManager",
|
||||
components: { AddPolicy, EditPolicy, PolicyOverview, PolicySubTableTabs },
|
||||
components: { PolicyForm, PolicyOverview, PolicySubTableTabs },
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
return {
|
||||
showAddPolicyModal: false,
|
||||
showEditPolicyModal: false,
|
||||
showPolicyFormModal: false,
|
||||
showPolicyOverviewModal: false,
|
||||
policyPkSelected: null,
|
||||
selected: [],
|
||||
pagination: {
|
||||
rowsPerPage: 0,
|
||||
sortBy: "id",
|
||||
@@ -175,17 +180,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getPolicies () {
|
||||
this.clearRow();
|
||||
this.$store.dispatch('automation/getPolicies');
|
||||
this.$store.dispatch('automation/loadPolicies');
|
||||
},
|
||||
hideAutomationManager () {
|
||||
this.$store.commit("TOGGLE_AUTOMATION_MANAGER", false);
|
||||
},
|
||||
policyRowSelected (pk) {
|
||||
this.$store.commit('automation/setSelectedPolicy', pk);
|
||||
this.$store.dispatch('automation/loadPolicyChecks', pk);
|
||||
this.$store.dispatch('automation/loadPolicyAutomatedTasks', pk);
|
||||
this.policyPkSelected = pk;
|
||||
policyRowSelected ({added, keys, rows}) {
|
||||
|
||||
// First key of the array is the selected row pk
|
||||
this.$store.commit('automation/setSelectedPolicy', keys[0]);
|
||||
this.$store.dispatch('automation/loadPolicyChecks', keys[0]);
|
||||
this.$store.dispatch('automation/loadPolicyAutomatedTasks', keys[0]);
|
||||
},
|
||||
clearRow () {
|
||||
this.$store.commit('automation/setSelectedPolicy', null);
|
||||
@@ -193,23 +195,25 @@ export default {
|
||||
this.$store.commit('automation/setPolicyAutomatedTasks', {});
|
||||
},
|
||||
deletePolicy () {
|
||||
this.$q
|
||||
.dialog({
|
||||
this.$q.dialog({
|
||||
title: "Delete policy?",
|
||||
cancel: true,
|
||||
ok: { label: "Delete", color: "negative" }
|
||||
})
|
||||
.onOk(() => {
|
||||
axios.delete(`/automation/policies/${this.selectedRow}`).then(r => {
|
||||
this.getPolicies();
|
||||
this.notifySuccess(`Policy was deleted!`);
|
||||
});
|
||||
|
||||
this.$store.dispatch('automation/deletePolicy', this.selectedRow)
|
||||
.then(response => {
|
||||
this.notifySuccess(`Policy was deleted!`);
|
||||
})
|
||||
.catch(error => {
|
||||
this.notifyError(`An Error occured while deleting policy`);
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
toggleAutomationManager: state => state.toggleAutomationManager,
|
||||
policies: state => state.automation.policies,
|
||||
selectedRow: state => state.automation.selectedPolicy
|
||||
}),
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
<template>
|
||||
<q-card style="width: 60vw">
|
||||
<q-form @submit.prevent="addPolicy">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Add Policy</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Name:</div>
|
||||
<div class="col-10">
|
||||
<q-input outlined dense v-model="name" :rules="[ val => !!val || '*Required']" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Description:</div>
|
||||
<div class="col-10">
|
||||
<q-input outlined dense v-model="desc" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Active:</div>
|
||||
<div class="col-10">
|
||||
<q-toggle v-model="active" color="green" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Clients:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedClients"
|
||||
:options="clientOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Sites:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedSites"
|
||||
:options="siteOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row">
|
||||
<div class="col-2">Agents:</div>
|
||||
<div class="col-10">
|
||||
<q-select
|
||||
v-model="selectedAgents"
|
||||
:options="agentOptions"
|
||||
filled
|
||||
multiple
|
||||
use-chips
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
No Results
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</q-select>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
<q-btn label="Add" color="primary" type="submit" />
|
||||
</q-card-section>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
export default {
|
||||
name: "AddPolicy",
|
||||
mixins: [mixins],
|
||||
data () {
|
||||
return {
|
||||
name: "",
|
||||
desc: "",
|
||||
active: false,
|
||||
selectedAgents: [],
|
||||
selectedSites: [],
|
||||
selectedClients: [],
|
||||
clientOptions: [],
|
||||
siteOptions: [],
|
||||
agentOptions: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
addPolicy () {
|
||||
if (!this.name) {
|
||||
this.notifyError("Name is required!");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$q.loading.show();
|
||||
|
||||
let formData = {
|
||||
name: this.name,
|
||||
desc: this.desc,
|
||||
active: this.active,
|
||||
agents: this.selectedAgents.map(agent => agent.value),
|
||||
sites: this.selectedSites.map(site => site.value),
|
||||
clients: this.selectedClients.map(client => client.value)
|
||||
};
|
||||
|
||||
axios.post("/automation/policies/", formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("added");
|
||||
this.notifySuccess("Policy added! Now you can add Tasks and Checks!");
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getClients () {
|
||||
axios.get(`/clients/listclients/`).then(r => {
|
||||
this.clientOptions = r.data.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getSites () {
|
||||
axios.get(`/clients/listsites/`).then(r => {
|
||||
this.siteOptions = r.data.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
value: site.id
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getAgents () {
|
||||
axios.get(`/agents/listagents/`).then(r => {
|
||||
this.agentOptions = r.data.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
value: agent.pk
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.getClients();
|
||||
this.getSites();
|
||||
this.getAgents();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<q-card style="width: 60vw">
|
||||
<q-form @submit.prevent="editPolicy">
|
||||
<q-form @submit.prevent="submit">
|
||||
<q-card-section class="row items-center">
|
||||
<div class="text-h6">Edit Policy</div>
|
||||
<div class="text-h6">{{ title }}</div>
|
||||
<q-space />
|
||||
<q-btn icon="close" flat round dense v-close-popup />
|
||||
</q-card-section>
|
||||
@@ -85,20 +85,20 @@
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section class="row items-center">
|
||||
<q-btn label="Edit" color="primary" type="submit" />
|
||||
<q-btn :label="title" color="primary" type="submit" />
|
||||
</q-card-section>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import mixins from "@/mixins/mixins";
|
||||
import dropdown_formatter from "@/mixins/dropdown_formatter";
|
||||
|
||||
export default {
|
||||
name: "EditPolicy",
|
||||
mixins: [mixins],
|
||||
props: ["pk"],
|
||||
name: "PolicyForm",
|
||||
mixins: [mixins, dropdown_formatter],
|
||||
props: {"pk": Number},
|
||||
data () {
|
||||
return {
|
||||
name: "",
|
||||
@@ -112,9 +112,14 @@ export default {
|
||||
agentOptions: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title () {
|
||||
return (this.pk) ? "Edit Policy" : "Add Policy";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPolicy () {
|
||||
axios.get(`/automation/policies/${this.pk}/`).then(r => {
|
||||
this.$store.dispatch("automation/loadPolicy", this.pk).then(r => {
|
||||
|
||||
this.name = r.data.name;
|
||||
this.desc = r.data.desc;
|
||||
@@ -139,14 +144,14 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
editPolicy () {
|
||||
submit () {
|
||||
if (!this.name) {
|
||||
this.notifyError("Name is required!");
|
||||
return false;
|
||||
}
|
||||
|
||||
this.$q.loading.show();
|
||||
|
||||
|
||||
let formData = {
|
||||
name: this.name,
|
||||
desc: this.desc,
|
||||
@@ -155,67 +160,73 @@ export default {
|
||||
sites: this.selectedSites.map(site => site.value),
|
||||
clients: this.selectedClients.map(client => client.value)
|
||||
};
|
||||
|
||||
if (this.pk) {
|
||||
this.$store.dispatch("automation/editPolicy", this.pk, formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("edited");
|
||||
this.notifySuccess("Policy edited!");
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
|
||||
axios.put(`/automation/policies/${this.pk}/`, formData)
|
||||
} else {
|
||||
|
||||
this.$store.dispatch("automation/addPolicy", formData)
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("refresh");
|
||||
this.notifySuccess("Policy added! Now you can add Tasks and Checks!");
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
|
||||
}
|
||||
},
|
||||
getClients () {
|
||||
this.$store.dispatch("loadClients")
|
||||
.then(r => {
|
||||
this.$q.loading.hide();
|
||||
this.$emit("close");
|
||||
this.$emit("edited");
|
||||
this.notifySuccess("Policy edited!");
|
||||
this.clientOptions = this.formatClient(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getClients () {
|
||||
|
||||
axios.get(`/clients/listclients/`).then(r => {
|
||||
this.clientOptions = r.data.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
};
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getSites () {
|
||||
|
||||
axios.get(`/clients/listsites/`).then(r => {
|
||||
this.siteOptions = r.data.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
value: site.id
|
||||
};
|
||||
this.$store.dispatch("loadSites")
|
||||
.then(r => {
|
||||
this.siteOptions = this.formatSites(r.data);
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
getAgents () {
|
||||
|
||||
axios.get(`/agents/listagents/`).then(r => {
|
||||
this.agentOptions = r.data.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
value: agent.pk
|
||||
};
|
||||
this.$store.dispatch("loadAgents")
|
||||
.then(r => {
|
||||
this.agentOptions = this.formatAgents(r.data)
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
this.$q.loading.hide();
|
||||
this.notifyError(e.response.data);
|
||||
});
|
||||
},
|
||||
},
|
||||
mounted () {
|
||||
this.getPolicy();
|
||||
//If pk prop is set that means we are editting
|
||||
if (this.pk) {
|
||||
this.getPolicy();
|
||||
}
|
||||
|
||||
this.getClients();
|
||||
this.getSites();
|
||||
this.getAgents();
|
||||
28
src/mixins/dropdown_formatter.js
Normal file
28
src/mixins/dropdown_formatter.js
Normal file
@@ -0,0 +1,28 @@
|
||||
export default {
|
||||
methods: {
|
||||
formatClients (clients) {
|
||||
return clients.map(client => {
|
||||
return {
|
||||
label: client.client,
|
||||
value: client.id
|
||||
};
|
||||
});
|
||||
},
|
||||
formatSites (sites) {
|
||||
return sites.map(site => {
|
||||
return {
|
||||
label: `${site.client_name}\\${site.site}`,
|
||||
value: site.id
|
||||
};
|
||||
});
|
||||
},
|
||||
formatAgents (agents) {
|
||||
return agents.map(agent => {
|
||||
return {
|
||||
label: `${agent.client}\\${agent.site}\\${agent.hostname}`,
|
||||
value: agent.pk
|
||||
};
|
||||
});
|
||||
},
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
import axios from 'axios';
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
},
|
||||
|
||||
actions: {
|
||||
getPolicies (context) {
|
||||
loadPolicies (context) {
|
||||
axios.get("/automation/policies/").then(r => {
|
||||
context.commit("SET_POLICIES", r.data);
|
||||
})
|
||||
@@ -49,5 +49,19 @@ export default {
|
||||
context.commit("setPolicyChecks", r.data);
|
||||
});
|
||||
},
|
||||
loadPolicy (context, pk) {
|
||||
return axios.get(`/automation/policies/${pk}/`);
|
||||
},
|
||||
addPolicy (context, data) {
|
||||
return axios.post("/automation/policies/", data);
|
||||
},
|
||||
editpolicy (context, data) {
|
||||
return axios.put(`/automation/policies/${this.pk}/`, formData)
|
||||
},
|
||||
deletePolicy (context, pk) {
|
||||
return axios.delete(`/automation/policies/${pk}`).then(r => {
|
||||
context.dispatch("getPolicies");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ export const store = new Vuex.Store({
|
||||
installedSoftware: [],
|
||||
scripts: [],
|
||||
toggleScriptManager: false,
|
||||
toggleAutomationManager: false
|
||||
},
|
||||
getters: {
|
||||
loggedIn(state) {
|
||||
@@ -64,10 +63,7 @@ export const store = new Vuex.Store({
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
TOGGLE_AUTOMATION_MANAGER(state, action) {
|
||||
state.toggleAutomationManager = action;
|
||||
},
|
||||
TOGGLE_SCRIPT_MANAGER(state, action) {
|
||||
TOGGLE_SCRIPT_MANAGER (state, action) {
|
||||
state.toggleScriptManager = action;
|
||||
},
|
||||
AGENT_TABLE_LOADING(state, visible) {
|
||||
@@ -153,6 +149,15 @@ export const store = new Vuex.Store({
|
||||
context.commit("getUpdatedSites", r.data);
|
||||
});
|
||||
},
|
||||
loadClients (context) {
|
||||
return axios.get("/clients/listclients/");
|
||||
},
|
||||
loadSites (context) {
|
||||
return axios.get("/clients/listsites/");
|
||||
},
|
||||
loadAgents (context) {
|
||||
return axios.get("/agents/listagents/");
|
||||
},
|
||||
loadTree({ commit }) {
|
||||
axios.get("/clients/loadtree/").then(r => {
|
||||
const input = r.data;
|
||||
|
||||
@@ -1,41 +1,181 @@
|
||||
import { shallowMount } from '@vue/test-utils'
|
||||
import AutomationManager from '@/components/automation/AutomationManager'
|
||||
import { mount, createLocalVue, createWrapper } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import AutomationManager from '@/components/automation/AutomationManager';
|
||||
import "@/quasar.js"
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
describe('AutomationManager.vue', () => {
|
||||
|
||||
it('calls vuex getPolicies action on mount', () => {
|
||||
const policiesData = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Test Policy",
|
||||
desc: "Description",
|
||||
active: true,
|
||||
clients: [],
|
||||
sites: [{},{}],
|
||||
agents: [{}]
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Test Policy 2",
|
||||
desc: "Description 2",
|
||||
active: false,
|
||||
clients: [],
|
||||
sites: [{},{}],
|
||||
agents: [{}]
|
||||
}
|
||||
];
|
||||
|
||||
const bodyWrapper = createWrapper(document.body);
|
||||
let wrapper;
|
||||
let state, mutations, actions, store;
|
||||
|
||||
// Runs before every test
|
||||
beforeEach(() => {
|
||||
|
||||
// Create the Test store
|
||||
state = {
|
||||
selectedPolicy: null,
|
||||
checks: {},
|
||||
automatedTasks: {},
|
||||
policies: policiesData,
|
||||
};
|
||||
|
||||
mutations = {
|
||||
setSelectedPolicy: jest.fn((state, key) => {state.selectedPolicy = key}),
|
||||
setPolicyChecks: jest.fn(),
|
||||
setPolicyAutomatedTasks: jest.fn(),
|
||||
|
||||
};
|
||||
|
||||
actions = {
|
||||
loadPolicies: jest.fn(),
|
||||
loadPolicyChecks: jest.fn(),
|
||||
loadPolicyAutomatedTasks: jest.fn(),
|
||||
deletePolicy: jest.fn()
|
||||
};
|
||||
|
||||
store = new Vuex.Store({
|
||||
modules: {
|
||||
automation: {
|
||||
namespaced: true,
|
||||
state,
|
||||
mutations,
|
||||
actions
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Mount all sub components except the ones specified
|
||||
wrapper = mount(AutomationManager, {
|
||||
store,
|
||||
localVue,
|
||||
stubs: [
|
||||
"PolicySubTableTabs",
|
||||
"PolicyForm"
|
||||
],
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('lists data in table', () => {
|
||||
|
||||
// Runs after every test
|
||||
// This is needed to remove q-dialogs since body doesn't rerender
|
||||
afterEach(() => {
|
||||
const dialogs = document.querySelectorAll(".q-dialog");
|
||||
dialogs.forEach(x => x.remove());
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
it('sends vuex setSelectedPolicy mutations and loadPolicyChecks and loadPolicyAutomatedTasks actions when policy is selected', () => {
|
||||
// The Tests
|
||||
it("calls vuex loadPolicies action on mount", () => {
|
||||
|
||||
expect(actions.loadPolicies).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it('send vuex TOGGLE_AUTOMATION_MANAGER mutation on close', () => {
|
||||
it("renders table when policies is set from store computed", () => {
|
||||
|
||||
const rows = wrapper.findAll("tbody > tr.q-tr").wrappers;
|
||||
expect(rows).toHaveLength(2);
|
||||
|
||||
});
|
||||
|
||||
it('shows edit policy modal on button press', () => {
|
||||
it("sends vuex mutations and actions when policy is selected", () => {
|
||||
|
||||
const row = wrapper.findAll("tbody > tr.q-tr").wrappers[1];
|
||||
|
||||
row.trigger('click');
|
||||
|
||||
expect(mutations.setSelectedPolicy).toHaveBeenCalledWith(expect.anything(), 2);
|
||||
expect(actions.loadPolicyChecks).toHaveBeenCalledWith(expect.anything(), 2);
|
||||
expect(actions.loadPolicyAutomatedTasks).toHaveBeenCalledWith(expect.anything(), 2);
|
||||
|
||||
});
|
||||
|
||||
it('shows add policy on button press and clear policy selected row', () => {
|
||||
it("shows edit policy modal on edit button press", async () => {
|
||||
|
||||
const button = wrapper.find({ref: "edit"});
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click")
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
|
||||
//Select Row
|
||||
await wrapper.find("tbody > tr.q-tr").trigger("click");
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('deletes selected policy', () => {
|
||||
it('shows add policy modal on button press', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "new"});
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('shows overview modal when button clicked', () => {
|
||||
it('deletes selected policy', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "delete"});
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
// Select Row
|
||||
await wrapper.find("tbody > tr.q-tr").trigger("click");
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
|
||||
//Get OK button and click it
|
||||
bodyWrapper.findAll(".q-btn").wrappers[1].trigger("click");
|
||||
|
||||
expect(actions.deletePolicy).toHaveBeenCalledWith(expect.anything(), 1);
|
||||
|
||||
});
|
||||
|
||||
it('calls vuex getPolicies action when refresh button clicked', () => {
|
||||
it('shows overview modal when button clicked', async () => {
|
||||
|
||||
const button = wrapper.find({ref: "overview"});
|
||||
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(false);
|
||||
await button.trigger("click");
|
||||
expect(bodyWrapper.find(".q-dialog").exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('calls vuex loadPolicies action when refresh button clicked and clears selected', () => {
|
||||
|
||||
const button = wrapper.find({ref: "refresh"});
|
||||
|
||||
button.trigger("click");
|
||||
expect(actions.loadPolicies).toHaveBeenCalled();
|
||||
expect(mutations.setSelectedPolicy).toHaveBeenCalledWith(expect.anything(), null);
|
||||
expect(mutations.setPolicyChecks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
expect(mutations.setPolicyAutomatedTasks).toHaveBeenCalledWith(expect.anything(), {});
|
||||
|
||||
});
|
||||
|
||||
|
||||
85
tests/unit/automation/automationmodals.spec.js
Normal file
85
tests/unit/automation/automationmodals.spec.js
Normal file
@@ -0,0 +1,85 @@
|
||||
import { mount, createLocalVue } from '@vue/test-utils';
|
||||
import Vuex from 'vuex';
|
||||
import PolicyForm from '@/components/automation/modals/PolicyForm';
|
||||
import "@/quasar.js"
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
describe('PolicyForm.vue', () => {
|
||||
|
||||
const clients = [];
|
||||
const sites = [];
|
||||
const agents = [];
|
||||
|
||||
const policy = {};
|
||||
|
||||
let actions, rootActions, store;
|
||||
|
||||
// Runs before every test
|
||||
beforeEach(() => {
|
||||
|
||||
rootActions = {
|
||||
loadClients: jest.fn( () => clients ),
|
||||
loadSites: jest.fn( () => sites ),
|
||||
loadAgents: jest.fn( () => agents ),
|
||||
};
|
||||
|
||||
actions = {
|
||||
loadPolicy: jest.fn( () => policy ),
|
||||
addPolicy: jest.fn(),
|
||||
editPolicy: jest.fn(),
|
||||
};
|
||||
|
||||
store = new Vuex.Store({
|
||||
actions: rootActions,
|
||||
modules: {
|
||||
automation: {
|
||||
namespaced: true,
|
||||
actions,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// The Tests
|
||||
it("calls vuex actions on mount", () => {
|
||||
|
||||
const wrapper = mount(PolicyForm, {
|
||||
localVue,
|
||||
store,
|
||||
});
|
||||
|
||||
expect(rootActions.loadClients).toHaveBeenCalled();
|
||||
expect(rootActions.loadSites).toHaveBeenCalled();
|
||||
expect(rootActions.loadAgents).toHaveBeenCalled();
|
||||
|
||||
// Not called unless pk prop is set
|
||||
expect(actions.loadPolicy).not.toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it("calls vuex actions on mount with pk prop set", () => {
|
||||
|
||||
const wrapper = mount(PolicyForm, {
|
||||
localVue,
|
||||
store,
|
||||
propsData: {
|
||||
pk: 1
|
||||
}
|
||||
});
|
||||
|
||||
expect(rootActions.loadClients).toHaveBeenCalled();
|
||||
expect(rootActions.loadSites).toHaveBeenCalled();
|
||||
expect(rootActions.loadAgents).toHaveBeenCalled();
|
||||
expect(actions.loadPolicy).toHaveBeenCalled();
|
||||
|
||||
})
|
||||
|
||||
/*it("renders the client, site, and agent dropdowns correctly", async () => {
|
||||
|
||||
})*/
|
||||
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user