Skip to content

Commit

Permalink
EW-694 working on UX requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
psachmann committed Feb 1, 2024
1 parent b6b2edc commit b1ba6d9
Show file tree
Hide file tree
Showing 10 changed files with 222 additions and 203 deletions.
Original file line number Diff line number Diff line change
@@ -1,95 +1,104 @@
import RoomsModule from "@/store/rooms";
import UploadModal from "./UploadModal.vue";
import CommonCartridgeImportModal from "./CommonCartridgeImportModal.vue";
import setupStores from "@@/tests/test-utils/setupStores";
import createComponentMocks from "@@/tests/test-utils/componentMocks";
import { mount, MountOptions } from "@vue/test-utils";
import Vue from "vue";
import LoadingStateModule from "@/store/loading-state";
import NotifierModule from "@/store/notifier";

jest.mock("@/utils/inject", () => ({
__esModule: true,
...jest.requireActual("@/utils/inject"),
injectStrict: jest.fn(),
}));

describe("@/components/molecules/UploadModal", () => {
import {
I18N_KEY,
LOADING_STATE_MODULE_KEY,
NOTIFIER_MODULE_KEY,
ROOMS_MODULE_KEY,
} from "@/utils/inject";
import { i18nMock } from "@@/tests/test-utils";
import { createModuleMocks } from "@/utils/mock-store-module";

describe("@/components/molecules/CommonCartridgeImportModal", () => {
const setup = () => {
document.body.setAttribute("data-app", "true");
setupStores({
loadingStateModule: LoadingStateModule,
notifierModule: NotifierModule,
roomsModule: RoomsModule,
});
const wrapper = mount(UploadModal as MountOptions<Vue>, {
const wrapper = mount(CommonCartridgeImportModal as MountOptions<Vue>, {
...createComponentMocks({
i18n: true,
}),
propsData: {
isOpen: false,
},
provide: {
[I18N_KEY.valueOf()]: i18nMock,
[LOADING_STATE_MODULE_KEY.valueOf()]:
createModuleMocks(LoadingStateModule),
[NOTIFIER_MODULE_KEY.valueOf()]: createModuleMocks(NotifierModule),
[ROOMS_MODULE_KEY.valueOf()]: createModuleMocks(RoomsModule),
},
});
return {
wrapper,
};
return { wrapper };
};

describe("when uploading a file", () => {
it("should open and close the modal", async () => {
const { wrapper } = setup();
const dialog = wrapper.find(".upload-dialog");
const uploadDialog = wrapper.vm.$refs.uploadDialog as any;
const importDialog = wrapper.vm.$refs.commonCartridgeImportDialog as any;

expect(dialog.exists()).toBe(true);
expect(uploadDialog.isOpen).toBe(false);
expect(importDialog).toBeDefined();
expect(importDialog.value).toBe(false);

await wrapper.setProps({
isOpen: true,
});

expect(uploadDialog.isOpen).toBe(true);
expect(importDialog.value).toBe(true);

await wrapper.setProps({
isOpen: false,
});

expect(uploadDialog.isOpen).toBe(false);
expect(importDialog.value).toBe(false);
});

it("should view upload button after selecting a file", async () => {
it("should enabled confirm button after selecting a file", async () => {
const { wrapper } = setup();
const uploadDialog = wrapper.vm.$refs.uploadDialog as any;

expect(uploadDialog.buttons).toEqual(["cancel"]);

await wrapper.setProps({
isOpen: true,
});

const confirmBtn = wrapper.find("[data-testid='dialog-confirm-btn']");

expect(confirmBtn.exists()).toBe(true);
expect(confirmBtn.vm.$props.disabled).toBe(true);

await wrapper.setData({
file: new File([""], "filename"),
});

expect(uploadDialog.buttons).toEqual(["cancel", "confirm"]);
expect(confirmBtn.vm.$props.disabled).toBe(false);
});

it("should upload file and trigger events dialog-confirmed and dialog-closed", async () => {
const { wrapper } = setup();
const dialog = wrapper.find(".upload-dialog");

await wrapper.setProps({
isOpen: true,
});

const confirmBtn = wrapper.find("[data-testid='dialog-confirm-btn']");

await wrapper.setData({
file: new File([""], "filename"),
});

const confirmBtn = wrapper.find("[data-testId='dialog-confirm']");
await confirmBtn.trigger("click");

confirmBtn.trigger("click");

const emitted = dialog.emitted();
const emitted = wrapper.emitted();

expect(emitted["dialog-confirmed"]).toHaveLength(1);
expect(emitted["update-rooms"]).toHaveLength(1);
expect(emitted["dialog-closed"]).toHaveLength(1);
});
});
Expand All @@ -102,7 +111,7 @@ describe("@/components/molecules/UploadModal", () => {
isOpen: true,
});

const btnCancel = wrapper.find("[data-testId='dialog-cancel']");
const btnCancel = wrapper.find("[data-testid='dialog-cancel-btn']");

btnCancel.trigger("click");

Expand Down
148 changes: 148 additions & 0 deletions src/components/molecules/CommonCartridgeImportModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<template>
<v-dialog
ref="commonCartridgeImportDialog"
:value="isOpen"
:max-width="maxWidth"
@click:outside="$emit('dialog-closed', false)"
@keydown.esc="$emit('dialog-closed', false)"
data-testid="common-cartridge-import-dialog"
>
<v-card :ripple="false">
<v-card-title data-testid="dialog-title">
{{ $t("pages.rooms.ccImportCourse.title") }}
</v-card-title>
<v-card-text class="text--primary">
<v-file-input
v-model="file"
:label="$t('pages.rooms.ccImportCourse.fileInputLabel')"
:prepend-icon="mdiUpload"
accept=".imscc, .zip"
clearable
show-size
/>
</v-card-text>
<v-card-actions>
<div class="button-section button-left">
<v-btn data-testid="dialog-cancel-btn" depressed @click="cancel">
{{ $t("common.labels.close") }}
</v-btn>
</div>
<v-spacer />
<div class="button-section button-right">
<v-btn
data-testid="dialog-confirm-btn"
color="primary"
:disabled="importButtonDisabled"
@click="confirm"
>
{{ $t("pages.rooms.ccImportCourse.confirm") }}
</v-btn>
</div>
</v-card-actions>
</v-card>
</v-dialog>
</template>

<script lang="ts">
import { computed, defineComponent, ref } from "vue";
import {
I18N_KEY,
LOADING_STATE_MODULE_KEY,
NOTIFIER_MODULE_KEY,
ROOMS_MODULE_KEY,
injectStrict,
} from "@/utils/inject";
import { mdiUpload } from "@mdi/js";
export default defineComponent({
name: "CommonCartridgeImportModal",
model: {
prop: "isOpen",
event: "dialog-closed",
},
props: {
isOpen: {
type: Boolean,
required: true,
},
maxWidth: {
type: Number,
default: 480,
},
},
emits: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
"dialog-closed": (value: boolean): boolean => true,
"update-rooms": (): boolean => true,
},
setup: (_, { emit }) => {
const i18n = injectStrict(I18N_KEY);
const loadingStateModule = injectStrict(LOADING_STATE_MODULE_KEY);
const notifierModule = injectStrict(NOTIFIER_MODULE_KEY);
const roomsModule = injectStrict(ROOMS_MODULE_KEY);
const file = ref<File | undefined>(undefined);
const importButtonDisabled = computed(() => {
return !file.value;
});
function cancel(): void {
emit("dialog-closed", false);
file.value = undefined;
}
async function confirm(): Promise<void> {
if (!file.value) {
return;
}
loadingStateModule.open({
text: i18n.tc("pages.rooms.ccImportCourse.loading"),
});
await roomsModule.uploadCourse(file.value);
emit("dialog-closed", false);
emit("update-rooms");
loadingStateModule.close();
const [newCourse] = roomsModule.getAllElements;
notifierModule.show({
status: roomsModule.getAlertData.status,
text: i18n
.t(roomsModule.getAlertData.text as string, { name: newCourse.title })
.toString(),
autoClose: roomsModule.getAlertData.autoClose,
timeout: roomsModule.getAlertData.timeout,
});
file.value = undefined;
}
return {
file,
importButtonDisabled,
mdiUpload,
cancel,
confirm,
};
},
});
</script>

<style lang="scss" scoped>
.button-left {
width: 25%;
text-align: left;
}
.button-right {
display: inline-block;
width: 75%;
text-align: right;
}
.button-section {
margin-bottom: calc(var(--space-base-vuetify) * 2);
}
.button-section > button {
margin-left: calc(var(--space-base-vuetify) * 2);
}
</style>
Loading

0 comments on commit b1ba6d9

Please sign in to comment.