Skip to content

Commit

Permalink
Add CaseStatusSelect group tests, refactor to script setup, and fix a…
Browse files Browse the repository at this point in the history
… couple bugs
  • Loading branch information
wssheldon committed Dec 6, 2023
1 parent 1e3fc95 commit 853e381
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 70 deletions.
164 changes: 94 additions & 70 deletions src/dispatch/static/dispatch/src/case/CaseStatusSelectGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,83 +70,107 @@
</v-item-group>
</template>

<script>
import { mapActions } from "vuex"
<script setup>
import { computed, watch, ref } from "vue"
import { useStore } from "vuex"
import { useSavingState } from "@/composables/useSavingState"
import DTooltip from "@/components/DTooltip.vue"
import CaseApi from "@/case/api"
export default {
name: "CaseStatusSelectGroup",
props: {
modelValue: {
type: Object,
required: false,
default: () => ({}),
},
const props = defineProps({
modelValue: {
type: Object,
required: false,
default: () => ({}),
},
components: {
DTooltip,
})
const store = useStore()
const { setSaving } = useSavingState()
let selectedStatus = ref(null)
let dialogVisible = ref(false)
let activeStatus = ref(props.modelValue.status)
const statuses = computed(() => [
{
name: "New",
label: "Created",
color: "red",
hoverClass: "hover-card-three",
sheetClass: "rounded-s-xl arrow",
tooltip: props.modelValue.created_at,
},
data() {
return {
selectedStatus: null,
dialogVisible: false,
}
{
name: "Triage",
label: "Triaged",
color: "red",
hoverClass: "hover-card-two",
sheetClass: "arrow",
tooltip: props.modelValue.triage_at,
},
computed: {
statuses() {
return [
{
name: "New",
label: "New",
color: "red",
hoverClass: "hover-card-three",
sheetClass: "rounded-s-xl arrow",
tooltip: this.modelValue.created_at,
},
{
name: "Triage",
label: "Triaged",
color: "red",
hoverClass: "hover-card-two",
sheetClass: "arrow",
tooltip: this.modelValue.triage_at,
},
{
name: "Closed",
label: "Resolved",
color: "green",
hoverClass: "hover-card",
sheetClass: "arrow",
tooltip: this.modelValue.closed_at,
},
{
name: "Escalated",
label: "Escalated",
color: "red",
hoverClass: "",
sheetClass: "rounded-e-xl end-sheet",
tooltip: this.modelValue.escalated_at,
},
]
},
{
name: "Closed",
label: "Resolved",
color: "green",
hoverClass: "hover-card",
sheetClass: "arrow",
tooltip: props.modelValue.closed_at,
},
methods: {
...mapActions("case_management", ["save_page"]),
changeStatus(newStatus) {
// eslint-disable-next-line vue/no-mutating-props
this.modelValue.status = newStatus
this.save_page()
this.dialogVisible = false
this.selectedStatus = null
},
openDialog(newStatus) {
this.selectedStatus = newStatus
this.dialogVisible = true
},
isActiveStatus(status) {
return this.modelValue.status === status
},
{
name: "Escalated",
label: "Escalated",
color: "red",
hoverClass: "",
sheetClass: "rounded-e-xl end-sheet",
tooltip: props.modelValue.escalated_at,
},
])
const changeStatus = async (newStatus) => {
const caseDetails = store.state.case_management.selected
const previousStatus = activeStatus.value
// Optimistically update the UI
activeStatus.value = newStatus
selectedStatus.value = null
dialogVisible.value = false
caseDetails.status = newStatus
try {
setSaving(true)
await CaseApi.update(caseDetails.id, caseDetails)
setSaving(false)
} catch (e) {
console.error(`Failed to update case status`, e)
// If the API call fails, revert the active status change
activeStatus.value = previousStatus
store.commit(
"notification_backend/addBeNotification",
{
text: `Failed to update case status`,
type: "exception",
},
{ root: true }
)
}
}
const openDialog = (newStatus) => {
selectedStatus.value = newStatus
dialogVisible.value = true
}
watch(
() => props.modelValue.status,
(newStatus) => {
activeStatus.value = newStatus
}
)
const isActiveStatus = (status) => {
return activeStatus.value === status
}
</script>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { mount } from "@vue/test-utils"
import { createStore } from "vuex"
import { createVuetify } from "vuetify"
import * as components from "vuetify/components"
import * as directives from "vuetify/directives"
import { describe, expect, it, vi, afterEach, beforeEach } from "vitest"
import CaseStatusSelectGroup from "@/case/CaseStatusSelectGroup.vue"
import CaseApi from "@/case/api"

const vuetify = createVuetify({
components,
directives,
})

global.ResizeObserver = require("resize-observer-polyfill")

describe("CaseStatusSelectGroup", () => {
let actions
let mockStore
let wrapper

beforeEach(() => {
// Mock the store and actions
actions = {
addBeNotification: vi.fn(),
}

mockStore = createStore({
modules: {
notification_backend: {
namespaced: true,
actions,
},
case_management: {
namespaced: true,
state: {
selected: {
id: 1,
status: "New",
},
},
},
},
})

// Mock the API
mockUpdate = vi.spyOn(CaseApi, "update").mockImplementation(() => Promise.resolve())

Check failure on line 47 in src/dispatch/static/dispatch/src/tests/CaseStatusSelectGroup.spec.js

View workflow job for this annotation

GitHub Actions / build

'mockUpdate' is not defined

// Mount the component
wrapper = mount(CaseStatusSelectGroup, {
props: {
modelValue: {
status: "New",
created_at: "2022-01-01",
},
},
global: {
plugins: [mockStore, vuetify], // 👈
},
})
})

afterEach(() => {
vi.restoreAllMocks()
})

it("mounts correctly", () => {
expect(wrapper.exists()).toBe(true)
})

it("opens dialog on status click", async () => {
await wrapper.find(".overlap-card").trigger("click")
expect(wrapper.vm.dialogVisible).toBe(true)
})
})

0 comments on commit 853e381

Please sign in to comment.