-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
85a4120
commit 6178f20
Showing
18 changed files
with
573 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
188 changes: 188 additions & 0 deletions
188
src/modules/feature/board-deleted-element/DeletedElement.unit.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
import { ContentElementType, DeletedElementResponse } from "@/serverApi/v3"; | ||
import { timestampsResponseFactory } from "@@/tests/test-utils"; | ||
import { | ||
createTestingI18n, | ||
createTestingVuetify, | ||
} from "@@/tests/test-utils/setup"; | ||
import { useBoardFocusHandler, useBoardPermissions } from "@data-board"; | ||
import { createMock, DeepMocked } from "@golevelup/ts-jest"; | ||
import { WarningAlert } from "@ui-alert"; | ||
import { mount } from "@vue/test-utils"; | ||
import { nextTick } from "vue"; | ||
import { ComponentProps } from "vue-component-type-helpers"; | ||
import DeletedElement from "./DeletedElement.vue"; | ||
import DeletedElementMenu from "./DeletedElementMenu.vue"; | ||
|
||
jest.mock("@data-board"); | ||
|
||
const DELETED_ELEMENT: DeletedElementResponse = { | ||
id: "deleted-element-id", | ||
content: { | ||
deletedElementType: ContentElementType.ExternalTool, | ||
title: "Deleted Tool", | ||
}, | ||
type: ContentElementType.Deleted, | ||
timestamps: timestampsResponseFactory.build(), | ||
}; | ||
|
||
describe("DeletedElement", () => { | ||
let useBoardFocusHandlerMock: DeepMocked< | ||
ReturnType<typeof useBoardFocusHandler> | ||
>; | ||
let useBoardPermissionsMock: DeepMocked< | ||
ReturnType<typeof useBoardPermissions> | ||
>; | ||
|
||
beforeEach(() => { | ||
useBoardFocusHandlerMock = | ||
createMock<ReturnType<typeof useBoardFocusHandler>>(); | ||
useBoardPermissionsMock = createMock< | ||
ReturnType<typeof useBoardPermissions> | ||
>({ isTeacher: true }); | ||
|
||
jest.mocked(useBoardFocusHandler).mockReturnValue(useBoardFocusHandlerMock); | ||
jest.mocked(useBoardPermissions).mockReturnValue(useBoardPermissionsMock); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
const getWrapper = ( | ||
props: ComponentProps<typeof DeletedElement> = { | ||
element: DELETED_ELEMENT, | ||
isEditMode: false, | ||
} | ||
) => { | ||
const wrapper = mount(DeletedElement, { | ||
global: { | ||
plugins: [createTestingVuetify(), createTestingI18n()], | ||
}, | ||
props, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("when the user is not a teacher", () => { | ||
const setup = () => { | ||
useBoardPermissionsMock.isTeacher = false; | ||
|
||
const { wrapper } = getWrapper({ | ||
element: DELETED_ELEMENT, | ||
isEditMode: true, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
it("should not show the element", async () => { | ||
const { wrapper } = setup(); | ||
|
||
const deletedElement = wrapper.findComponent({ ref: "deletedElement" }); | ||
|
||
expect(deletedElement.isVisible()).toEqual(false); | ||
}); | ||
}); | ||
|
||
describe("Menu", () => { | ||
describe("when in edit mode", () => { | ||
const setup = () => { | ||
const { wrapper } = getWrapper({ | ||
element: DELETED_ELEMENT, | ||
isEditMode: true, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
it("should display the tree dot menu", async () => { | ||
const { wrapper } = setup(); | ||
|
||
const threeDotMenu = wrapper.findComponent(DeletedElementMenu); | ||
|
||
expect(threeDotMenu.isVisible()).toEqual(true); | ||
}); | ||
}); | ||
|
||
describe("when not in edit mode", () => { | ||
const setup = () => { | ||
const { wrapper } = getWrapper({ | ||
element: DELETED_ELEMENT, | ||
isEditMode: false, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
it("should not display the tree dot menu", async () => { | ||
const { wrapper } = setup(); | ||
|
||
const threeDotMenu = wrapper.findComponent(DeletedElementMenu); | ||
|
||
expect(threeDotMenu.exists()).toEqual(false); | ||
}); | ||
}); | ||
|
||
describe("when deleting the element", () => { | ||
const setup = () => { | ||
const { wrapper } = getWrapper({ | ||
element: DELETED_ELEMENT, | ||
isEditMode: true, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
it("should emit an event", async () => { | ||
const { wrapper } = setup(); | ||
|
||
wrapper.findComponent(DeletedElementMenu).vm.$emit("delete:element"); | ||
await nextTick(); | ||
|
||
expect(wrapper.emitted("delete:element")).toEqual([ | ||
[DELETED_ELEMENT.id], | ||
]); | ||
}); | ||
}); | ||
}); | ||
|
||
describe("Alert", () => { | ||
describe("when the deleted element was an external tool element", () => { | ||
const setup = () => { | ||
const { wrapper } = getWrapper({ | ||
element: DELETED_ELEMENT, | ||
isEditMode: true, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
it("should display a warning", async () => { | ||
const { wrapper } = setup(); | ||
|
||
const alert = wrapper.findComponent(WarningAlert); | ||
|
||
expect(alert.text()).toEqual( | ||
"components.cardElement.deletedElement.warning.externalToolElement" | ||
); | ||
}); | ||
}); | ||
}); | ||
}); |
71 changes: 71 additions & 0 deletions
71
src/modules/feature/board-deleted-element/DeletedElement.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<template> | ||
<VCard | ||
v-show="isTeacher" | ||
class="mb-4" | ||
data-testid="board-deleted-element" | ||
elevation="0" | ||
variant="outlined" | ||
ref="deletedElement" | ||
:ripple="false" | ||
> | ||
<WarningAlert | ||
v-if=" | ||
element.content.deletedElementType === ContentElementType.ExternalTool | ||
" | ||
> | ||
{{ | ||
$t( | ||
"components.cardElement.deletedElement.warning.externalToolElement", | ||
{ | ||
toolName: element.content.title, | ||
} | ||
) | ||
}} | ||
</WarningAlert> | ||
<ContentElementBar :has-grey-background="true" :icon="mdiPuzzleOutline"> | ||
<template #title> | ||
{{ element.content.title }} | ||
</template> | ||
<template #menu> | ||
<DeletedElementMenu | ||
v-if="isEditMode" | ||
@delete:element="onDeleteElement" | ||
/> | ||
</template> | ||
</ContentElementBar> | ||
</VCard> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { ContentElementType, DeletedElementResponse } from "@/serverApi/v3"; | ||
import { useBoardFocusHandler, useBoardPermissions } from "@data-board"; | ||
import { mdiPuzzleOutline } from "@mdi/js"; | ||
import { WarningAlert } from "@ui-alert"; | ||
import { ContentElementBar } from "@ui-board"; | ||
import { PropType, Ref, ref, toRef } from "vue"; | ||
import DeletedElementMenu from "./DeletedElementMenu.vue"; | ||
const props = defineProps({ | ||
element: { | ||
type: Object as PropType<DeletedElementResponse>, | ||
required: true, | ||
}, | ||
isEditMode: { type: Boolean, required: true }, | ||
}); | ||
const emit = defineEmits<{ | ||
(e: "delete:element", elementId: string): void; | ||
}>(); | ||
const { isTeacher } = useBoardPermissions(); | ||
const autofocus: Ref<boolean> = ref(false); | ||
const element: Ref<DeletedElementResponse> = toRef(props, "element"); | ||
useBoardFocusHandler(element.value.id, ref(null), () => { | ||
autofocus.value = true; | ||
}); | ||
const onDeleteElement = () => { | ||
emit("delete:element", element.value.id); | ||
}; | ||
</script> |
47 changes: 47 additions & 0 deletions
47
src/modules/feature/board-deleted-element/DeletedElementMenu.unit.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { | ||
createTestingI18n, | ||
createTestingVuetify, | ||
} from "@@/tests/test-utils/setup"; | ||
import { BoardMenuActionDelete } from "@ui-board"; | ||
import { shallowMount } from "@vue/test-utils"; | ||
import DeletedElementMenu from "./DeletedElementMenu.vue"; | ||
|
||
describe("DeletedElementMenu", () => { | ||
const getWrapper = () => { | ||
document.body.setAttribute("data-app", "true"); | ||
|
||
const wrapper = shallowMount(DeletedElementMenu, { | ||
global: { | ||
plugins: [createTestingVuetify(), createTestingI18n()], | ||
}, | ||
}); | ||
|
||
return { | ||
wrapper, | ||
}; | ||
}; | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
}); | ||
|
||
describe("Delete Button", () => { | ||
it("should have a menu option to delete", () => { | ||
const { wrapper } = getWrapper(); | ||
|
||
const menuItem = wrapper.findComponent(BoardMenuActionDelete); | ||
|
||
expect(menuItem.exists()).toEqual(true); | ||
}); | ||
|
||
it("should emit the delete event on click", async () => { | ||
const { wrapper } = getWrapper(); | ||
|
||
const menuItem = wrapper.findComponent(BoardMenuActionDelete); | ||
|
||
await menuItem.trigger("click"); | ||
|
||
expect(wrapper.emitted("delete:element")).toBeDefined(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.