4797-workerNotificationManager #107
|
@ -13,5 +13,6 @@
|
||||||
],
|
],
|
||||||
"[vue]": {
|
"[vue]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
}
|
},
|
||||||
|
"cSpell.words": ["axios"]
|
||||||
alexm marked this conversation as resolved
|
|||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"test:unit:ci": "vitest run"
|
"test:unit:ci": "vitest run"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quasar/cli": "^2.2.1",
|
"@quasar/cli": "^2.3.0",
|
||||||
"@quasar/extras": "^1.16.4",
|
"@quasar/extras": "^1.16.4",
|
||||||
"axios": "^1.4.0",
|
"axios": "^1.4.0",
|
||||||
"chromium": "^3.0.3",
|
"chromium": "^3.0.3",
|
||||||
|
|
|
@ -89,6 +89,7 @@ async function fetch(data) {
|
||||||
watch(formData, () => (hasChanges.value = true), { deep: true });
|
watch(formData, () => (hasChanges.value = true), { deep: true });
|
||||||
|
|
||||||
emit('onFetch', data);
|
emit('onFetch', data);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reset() {
|
async function reset() {
|
||||||
|
|
|
@ -249,9 +249,6 @@ function goToAction() {
|
||||||
.grid-style-transition {
|
.grid-style-transition {
|
||||||
transition: transform 0.28s, background-color 0.28s;
|
transition: transform 0.28s, background-color 0.28s;
|
||||||
}
|
}
|
||||||
.maxwidth {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<i18n>
|
<i18n>
|
||||||
|
|
|
@ -1,56 +0,0 @@
|
||||||
<script setup>
|
|
||||||
import { reactive, watch } from 'vue';
|
|
||||||
|
|
||||||
const customer = reactive({
|
|
||||||
name: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => customer.name);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<QPage class="q-pa-md">
|
|
||||||
<QCard class="q-pa-md">
|
|
||||||
<QForm @submit="onSubmit" @reset="onReset" class="q-gutter-md">
|
|
||||||
<QInput
|
|
||||||
filled
|
|
||||||
v-model="customer.name"
|
|
||||||
label="Your name *"
|
|
||||||
hint="Name and surname"
|
|
||||||
lazy-rules
|
|
||||||
:rules="[(val) => (val && val.length > 0) || 'Please type something']"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<QInput
|
|
||||||
filled
|
|
||||||
type="number"
|
|
||||||
v-model="age"
|
|
||||||
label="Your age *"
|
|
||||||
lazy-rules
|
|
||||||
:rules="[
|
|
||||||
(val) => (val !== null && val !== '') || 'Please type your age',
|
|
||||||
(val) => (val > 0 && val < 100) || 'Please type a real age',
|
|
||||||
]"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<QBtn label="Submit" type="submit" color="primary" />
|
|
||||||
<QBtn
|
|
||||||
label="Reset"
|
|
||||||
type="reset"
|
|
||||||
color="primary"
|
|
||||||
flat
|
|
||||||
class="q-ml-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</QForm>
|
|
||||||
</QCard>
|
|
||||||
</QPage>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.card {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 60em;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,10 +1,12 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
import { computed, onMounted, onUpdated, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
|
import CrudModel from 'components/CrudModel.vue';
|
||||||
|
|
||||||
const $props = defineProps({
|
const $props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
type: Number,
|
type: Number,
|
||||||
|
@ -12,131 +14,139 @@ const $props = defineProps({
|
||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const entityId = computed(() => $props.id || route.params.id);
|
|
||||||
|
|
||||||
onMounted(() => fetch());
|
|
||||||
onUpdated(() => fetch());
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
const entityId = computed(() => $props.id || route.params.id);
|
||||||
const notifications = ref([]);
|
const URL_KEY = 'NotificationSubscriptions';
|
||||||
|
const active = ref();
|
||||||
async function fetch() {
|
const available = ref();
|
||||||
try {
|
|
||||||
await axios
|
|
||||||
.get(`NotificationSubscriptions/${entityId.value}/getList`)
|
|
||||||
.then(async (res) => {
|
|
||||||
if (res.data) {
|
|
||||||
notifications.value = res.data;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function disableNotification(notification) {
|
|
||||||
await axios
|
|
||||||
.delete(`NotificationSubscriptions/${notification.id}`)
|
|
||||||
.catch(() => (notification.active = true))
|
|
||||||
.then((res) => {
|
|
||||||
if (res.data) {
|
|
||||||
notification.id = null;
|
|
||||||
notification.active = false;
|
|
||||||
quasar.notify({
|
|
||||||
type: 'positive',
|
|
||||||
message: t('worker.notificationsManager.unsubscribed'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function toggleNotification(notification) {
|
async function toggleNotification(notification) {
|
||||||
|
try {
|
||||||
if (!notification.active) {
|
if (!notification.active) {
|
||||||
await disableNotification(notification);
|
await axios.delete(`${URL_KEY}/${notification.id}`);
|
||||||
|
swapEntry(active.value, available.value, notification.notificationFk);
|
||||||
} else {
|
} else {
|
||||||
await axios
|
const { data } = await axios.post(URL_KEY, {
|
||||||
.post(`NotificationSubscriptions`, {
|
|
||||||
notificationFk: notification.notificationFk,
|
notificationFk: notification.notificationFk,
|
||||||
userFk: entityId.value,
|
userFk: entityId.value,
|
||||||
})
|
});
|
||||||
.catch(() => (notification.active = false))
|
notification.id = data.id;
|
||||||
.then((res) => {
|
|
||||||
if (res.data) {
|
swapEntry(available.value, active.value, notification.notificationFk);
|
||||||
notification.id = res.data.id;
|
}
|
||||||
|
|
||||||
quasar.notify({
|
quasar.notify({
|
||||||
type: 'positive',
|
type: 'positive',
|
||||||
message: t('worker.notificationsManager.subscribed'),
|
message: t(
|
||||||
|
`worker.notificationsManager.${notification.active ? '' : 'un'}subscribed`
|
||||||
|
),
|
||||||
});
|
});
|
||||||
|
} catch {
|
||||||
|
notification.active = !notification.active;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const swapEntry = (from, to, key) => {
|
||||||
|
const element = from.get(key);
|
||||||
|
to.set(key, element);
|
||||||
|
from.delete(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
function setNotifications(data) {
|
||||||
|
active.value = new Map(data.active);
|
||||||
|
available.value = new Map(data.available);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<QPage>
|
<CrudModel
|
||||||
<QCard class="q-pa-md">
|
auto-load
|
||||||
alexm marked this conversation as resolved
jsegarra
commented
NotificationSubscriptions aparece 4 veces en este fichero, como verias de hacer una const para que sólo esté 1 vez? NotificationSubscriptions aparece 4 veces en este fichero, como verias de hacer una const para que sólo esté 1 vez?
|
|||||||
<QList>
|
:data-key="URL_KEY"
|
||||||
<div
|
:url="`${URL_KEY}/${entityId}/getList`"
|
||||||
v-show="
|
:default-reset="false"
|
||||||
notifications.filter(
|
:default-remove="false"
|
||||||
(notification) => notification.active == true
|
:default-save="false"
|
||||||
).length
|
@on-fetch="setNotifications"
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<QItemLabel header class="text-h6">
|
<template #body>
|
||||||
{{ t('worker.notificationsManager.activeNotifications') }}
|
|
||||||
</QItemLabel>
|
|
||||||
<QItem>
|
|
||||||
<div
|
<div
|
||||||
v-for="notification in notifications.filter(
|
v-for="(notifications, index) in [
|
||||||
(notification) => notification.active == true
|
[...active.values()],
|
||||||
)"
|
[...available.values()],
|
||||||
:key="notification.id"
|
]"
|
||||||
|
:key="notifications"
|
||||||
>
|
>
|
||||||
<QChip
|
<QList class="notificationList">
|
||||||
:key="notification.id"
|
<TransitionGroup>
|
||||||
:label="notification.name"
|
<QCard
|
||||||
text-color="white"
|
|
||||||
color="primary"
|
|
||||||
class="q-mr-sm"
|
|
||||||
removable
|
|
||||||
@remove="disableNotification(notification)"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</QItem>
|
|
||||||
</div>
|
|
||||||
<div v-show="notifications.length">
|
|
||||||
<QItemLabel header class="text-h6">
|
|
||||||
{{ t('worker.notificationsManager.availableNotifications') }}
|
|
||||||
</QItemLabel>
|
|
||||||
<div class="row">
|
|
||||||
<QItem
|
|
||||||
class="col-3"
|
|
||||||
:key="notification.notificationFk"
|
|
||||||
v-for="notification in notifications"
|
v-for="notification in notifications"
|
||||||
|
:key="notification.notificationFk"
|
||||||
|
class="q-pa-md"
|
||||||
>
|
>
|
||||||
|
<QItem>
|
||||||
|
<QItemSection avatar>
|
||||||
|
<QBtn
|
||||||
|
round
|
||||||
|
icon="mail"
|
||||||
|
:color="notification.active ? 'green' : 'grey'"
|
||||||
|
/>
|
||||||
|
</QItemSection>
|
||||||
<QItemSection>
|
<QItemSection>
|
||||||
<QItemLabel>{{ notification.name }}</QItemLabel>
|
<QItemLabel>{{ notification.name }}</QItemLabel>
|
||||||
<QItemLabel caption>{{
|
<QItemLabel caption>
|
||||||
notification.description
|
{{ notification.description }}
|
||||||
}}</QItemLabel>
|
</QItemLabel>
|
||||||
</QItemSection>
|
</QItemSection>
|
||||||
<QItemSection side top>
|
|
||||||
<QToggle
|
<QToggle
|
||||||
checked-icon="check"
|
checked-icon="check"
|
||||||
unchecked-icon="close"
|
unchecked-icon="close"
|
||||||
indeterminate-icon="block"
|
|
||||||
v-model="notification.active"
|
v-model="notification.active"
|
||||||
|
color="green"
|
||||||
@update:model-value="toggleNotification(notification)"
|
@update:model-value="toggleNotification(notification)"
|
||||||
/>
|
/>
|
||||||
</QItemSection>
|
|
||||||
</QItem>
|
</QItem>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</QList>
|
|
||||||
</QCard>
|
</QCard>
|
||||||
</QPage>
|
</TransitionGroup>
|
||||||
|
</QList>
|
||||||
|
<QSeparator
|
||||||
|
color="primary"
|
||||||
|
class="q-my-lg"
|
||||||
|
v-if="!index && available.size && active.size"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
</CrudModel>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notificationList {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
grid-gap: 10px;
|
||||||
|
|
||||||
|
.v-enter-active,
|
||||||
|
.v-leave-active {
|
||||||
|
transition: opacity 0.5s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-enter-from,
|
||||||
|
.v-leave-to {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-md) {
|
||||||
|
.notificationList {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: $breakpoint-xs) {
|
||||||
|
.notificationList {
|
||||||
|
grid-template-columns: repeat(1, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -10,7 +10,7 @@ export default {
|
||||||
component: RouterView,
|
component: RouterView,
|
||||||
redirect: { name: 'CustomerMain' },
|
redirect: { name: 'CustomerMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['CustomerList', 'CustomerPayments', 'CustomerCreate'],
|
main: ['CustomerList', 'CustomerPayments'],
|
||||||
card: ['CustomerBasicData'],
|
card: ['CustomerBasicData'],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
|
@ -27,7 +27,7 @@ export default {
|
||||||
title: 'list',
|
title: 'list',
|
||||||
icon: 'view_list',
|
icon: 'view_list',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Customer/CustomerList.vue')
|
component: () => import('src/pages/Customer/CustomerList.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'payments',
|
path: 'payments',
|
||||||
|
@ -36,17 +36,7 @@ export default {
|
||||||
title: 'webPayments',
|
title: 'webPayments',
|
||||||
icon: 'vn:onlinepayment',
|
icon: 'vn:onlinepayment',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Customer/CustomerPayments.vue')
|
component: () => import('src/pages/Customer/CustomerPayments.vue'),
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'create',
|
|
||||||
name: 'CustomerCreate',
|
|
||||||
meta: {
|
|
||||||
title: 'createCustomer',
|
|
||||||
icon: 'vn:addperson',
|
|
||||||
roles: ['developer'],
|
|
||||||
},
|
|
||||||
component: () => import('src/pages/Customer/CustomerCreate.vue'),
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -63,7 +53,8 @@ export default {
|
||||||
title: 'summary',
|
title: 'summary',
|
||||||
icon: 'launch',
|
icon: 'launch',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Customer/Card/CustomerSummary.vue'),
|
component: () =>
|
||||||
|
import('src/pages/Customer/Card/CustomerSummary.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'basic-data',
|
path: 'basic-data',
|
||||||
|
@ -72,7 +63,8 @@ export default {
|
||||||
title: 'basicData',
|
title: 'basicData',
|
||||||
icon: 'vn:settings',
|
icon: 'vn:settings',
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Customer/Card/CustomerBasicData.vue'),
|
component: () =>
|
||||||
|
import('src/pages/Customer/Card/CustomerBasicData.vue'),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -11,7 +11,7 @@ export default {
|
||||||
redirect: { name: 'WorkerMain' },
|
redirect: { name: 'WorkerMain' },
|
||||||
menus: {
|
menus: {
|
||||||
main: ['WorkerList'],
|
main: ['WorkerList'],
|
||||||
// card: ['WorkerNotificationsManager'],
|
card: ['WorkerNotificationsManager'],
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -46,15 +46,16 @@ export default {
|
||||||
},
|
},
|
||||||
component: () => import('src/pages/Worker/Card/WorkerSummary.vue'),
|
component: () => import('src/pages/Worker/Card/WorkerSummary.vue'),
|
||||||
},
|
},
|
||||||
// {
|
{
|
||||||
// name: 'WorkerNotificationsManager',
|
name: 'WorkerNotificationsManager',
|
||||||
// path: 'notifications',
|
path: 'notifications',
|
||||||
// meta: {
|
meta: {
|
||||||
// title: 'notifications',
|
title: 'notifications',
|
||||||
// icon: 'notifications',
|
icon: 'notifications',
|
||||||
// },
|
},
|
||||||
// component: () => import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
component: () =>
|
||||||
// },
|
import('src/pages/Worker/Card/WorkerNotificationsManager.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -1,36 +1,79 @@
|
||||||
xdescribe('WorkerNotificationsManager', () => {
|
describe('WorkerNotificationsManager', () => {
|
||||||
|
const salesPersonId = 18;
|
||||||
|
const developerId = 9;
|
||||||
|
|
||||||
|
const activeList = ':nth-child(1) > .q-list';
|
||||||
|
const availableList = ':nth-child(2) > .q-list';
|
||||||
|
const firstActiveNotification =
|
||||||
|
':nth-child(1) > .q-list > :nth-child(1) > .q-item > .q-toggle > .q-toggle__inner';
|
||||||
|
const firstAvailableNotification =
|
||||||
|
':nth-child(2) > .q-list > :nth-child(1) > .q-item > .q-toggle > .q-toggle__inner';
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const workerId = 1110;
|
|
||||||
cy.viewport(1280, 720);
|
cy.viewport(1280, 720);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error if you try to change a notification that is not yours', () => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
||||||
|
cy.get(firstAvailableNotification).click();
|
||||||
|
cy.notificationHas(
|
||||||
|
'.q-notification__message',
|
||||||
|
'The notification subscription of this worker cant be modified'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should active a notification that is yours', () => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/worker/${developerId}/notifications`);
|
||||||
|
cy.waitForElement(activeList);
|
||||||
|
cy.waitForElement(availableList);
|
||||||
|
|
||||||
|
cy.get(activeList)
|
||||||
|
.children()
|
||||||
|
.its('length')
|
||||||
|
.then((beforeSize) => {
|
||||||
|
cy.get(firstAvailableNotification).click();
|
||||||
|
cy.get(activeList)
|
||||||
|
.children()
|
||||||
|
.should('have.length', beforeSize + 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should deactivate a notification that is yours', () => {
|
||||||
|
cy.login('developer');
|
||||||
|
cy.visit(`/#/worker/${developerId}/notifications`);
|
||||||
|
cy.waitForElement(activeList);
|
||||||
|
cy.waitForElement(availableList);
|
||||||
|
|
||||||
|
cy.get(availableList)
|
||||||
|
.children()
|
||||||
|
.its('length')
|
||||||
|
.then((beforeSize) => {
|
||||||
|
cy.get(firstActiveNotification).click();
|
||||||
|
cy.get(availableList)
|
||||||
|
.children()
|
||||||
|
.should('have.length', beforeSize + 1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should active a notification if you are their boss', () => {
|
||||||
cy.login('salesBoss');
|
cy.login('salesBoss');
|
||||||
cy.visit(`/#/worker/${workerId}/notifications`);
|
cy.visit(`/#/worker/${salesPersonId}/notifications`);
|
||||||
});
|
cy.waitForElement(activeList);
|
||||||
|
cy.waitForElement(availableList);
|
||||||
|
|
||||||
it('should unsubscribe 2 notifications, check the unsubscription has been saved, subscribe to other one and should check the data has been saved', () => {
|
cy.get(activeList)
|
||||||
cy.get('.q-chip').should('have.length', 3);
|
.children()
|
||||||
cy.get('.q-toggle__thumb').eq(0).click();
|
.its('length')
|
||||||
cy.get('.q-notification__message').should(
|
.then((beforeSize) => {
|
||||||
'have.text',
|
cy.get(firstAvailableNotification).click();
|
||||||
'Unsubscribed from the notification'
|
cy.get(activeList)
|
||||||
);
|
.children()
|
||||||
cy.get('.q-chip > .q-icon').eq(0).click();
|
.should('have.length', beforeSize + 1);
|
||||||
|
|
||||||
cy.reload();
|
//Rollback
|
||||||
|
cy.get(firstActiveNotification).click();
|
||||||
cy.get('.q-chip').should('have.length', 1);
|
});
|
||||||
cy.get('.q-toggle__thumb').should('have.length', 3).eq(0).click();
|
|
||||||
cy.get('.q-notification__message').should(
|
|
||||||
'have.text',
|
|
||||||
'Subscribed to the notification'
|
|
||||||
);
|
|
||||||
cy.get('.q-toggle__thumb').should('have.length', 3).eq(1).click();
|
|
||||||
cy.get('.q-notification__message').should(
|
|
||||||
'have.text',
|
|
||||||
'Subscribed to the notification'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.reload();
|
|
||||||
|
|
||||||
cy.get('.q-chip').should('have.length', 3);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,6 +91,10 @@ Cypress.Commands.add('clickConfirm', () => {
|
||||||
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
|
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('notificationHas', (selector, text) => {
|
||||||
|
cy.get(selector).should('have.text', text);
|
||||||
|
});
|
||||||
|
|
||||||
Cypress.Commands.add('fillRow', (rowSelector, data) => {
|
Cypress.Commands.add('fillRow', (rowSelector, data) => {
|
||||||
// Usar el selector proporcionado para obtener la fila deseada
|
// Usar el selector proporcionado para obtener la fila deseada
|
||||||
cy.waitForElement('tbody');
|
cy.waitForElement('tbody');
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
import { vi, describe, expect, it, beforeAll, afterEach } from 'vitest';
|
||||||
import { createWrapper, axios } from 'app/test/vitest/helper';
|
import { createWrapper } from 'app/test/vitest/helper';
|
||||||
import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue';
|
import WorkerNotificationsManager from 'src/pages/Worker/Card/WorkerNotificationsManager.vue';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
describe('WorkerNotificationsManager', () => {
|
describe('WorkerNotificationsManager', () => {
|
||||||
let vm;
|
let vm;
|
||||||
const entityId = 1110;
|
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
vm = createWrapper(WorkerNotificationsManager, {
|
vm = createWrapper(WorkerNotificationsManager, {
|
||||||
propsData: {
|
global: {
|
||||||
id: entityId,
|
stubs: ['CrudModel'],
|
||||||
},
|
},
|
||||||
}).vm;
|
}).vm;
|
||||||
});
|
});
|
||||||
|
@ -18,83 +18,16 @@ describe('WorkerNotificationsManager', () => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('fetch()', () => {
|
describe('swapEntry()', () => {
|
||||||
it('should fetch notification subscriptions and role mappings', async () => {
|
it('should swap notification', async () => {
|
||||||
vi.spyOn(axios, 'get')
|
const from = ref(new Map());
|
||||||
.mockResolvedValueOnce({
|
const to = ref(new Map());
|
||||||
data: [
|
from.value.set(1, { notificationFk: 1 });
|
||||||
{
|
to.value.set(2, { notificationFk: 2 });
|
||||||
id: 1,
|
|
||||||
name: 'Name 1',
|
|
||||||
description: 'Description 1',
|
|
||||||
notificationFk: 1,
|
|
||||||
active: true
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
await vm.fetch();
|
|
||||||
|
|
||||||
expect(axios.get).toHaveBeenCalledWith(`NotificationSubscriptions/${entityId}/getList`);
|
await vm.swapEntry(from.value, to.value, 1);
|
||||||
expect(vm.notifications).toEqual([
|
expect(to.value.size).toBe(2);
|
||||||
{
|
expect(from.value.size).toBe(0);
|
||||||
id: 1,
|
|
||||||
notificationFk: 1,
|
|
||||||
name: 'Name 1',
|
|
||||||
description: 'Description 1',
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('disableNotification()', () => {
|
|
||||||
it('should disable the notification', async () => {
|
|
||||||
vi.spyOn(axios, 'delete').mockResolvedValue({ data: { count: 1 } });
|
|
||||||
vi.spyOn(vm.quasar, 'notify');
|
|
||||||
const subscriptionId = 1;
|
|
||||||
vm.notifications = [{ id: 1, active: true }];
|
|
||||||
|
|
||||||
await vm.disableNotification(vm.notifications[0]);
|
|
||||||
|
|
||||||
expect(axios.delete).toHaveBeenCalledWith(
|
|
||||||
`NotificationSubscriptions/${subscriptionId}`
|
|
||||||
);
|
|
||||||
expect(vm.notifications[0].id).toBeNull();
|
|
||||||
expect(vm.notifications[0].id).toBeFalsy();
|
|
||||||
expect(vm.quasar.notify).toHaveBeenCalledWith(
|
|
||||||
expect.objectContaining({ type: 'positive' })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('toggleNotification()', () => {
|
|
||||||
it('should activate the notification', async () => {
|
|
||||||
vi.spyOn(axios, 'post').mockResolvedValue({
|
|
||||||
data: { id: 1, notificationFk: 1 },
|
|
||||||
});
|
|
||||||
vm.notifications = [{ id: null, active: true, notificationFk: 1 }];
|
|
||||||
|
|
||||||
await vm.toggleNotification(vm.notifications[0]);
|
|
||||||
|
|
||||||
expect(axios.post).toHaveBeenCalledWith('NotificationSubscriptions', {
|
|
||||||
notificationFk: 1,
|
|
||||||
userFk: entityId,
|
|
||||||
});
|
|
||||||
expect(vm.notifications[0].id).toBe(1);
|
|
||||||
expect(vm.notifications[0].active).toBeTruthy();
|
|
||||||
expect(vm.quasar.notify).toHaveBeenCalledWith(
|
|
||||||
expect.objectContaining({ type: 'positive' })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should disable the notification', async () => {
|
|
||||||
vi.spyOn(vm, 'disableNotification');
|
|
||||||
vm.notifications = [{ id: 1, active: false, notificationFk: 1 }];
|
|
||||||
|
|
||||||
await vm.toggleNotification(vm.notifications[0]);
|
|
||||||
|
|
||||||
expect(vm.notifications[0].id).toBe(null);
|
|
||||||
expect(vm.notifications[0].active).toBeFalsy();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Este archivo seguro que hay que subirlo?
Creo que se puede poner a nivel de usuario.
Pero por si alguien mas lo usa. Que todos tengamos que darle la primera vez a que no te lo marque
Creo que se puede poner a nivel de usuario.
Pero por si alguien mas lo usa. Que todos tengamos que darle la primera vez a que no te lo marque