Skip to content

Commit

Permalink
Merge branch 'main' into DMED-119-integration-of-search-environment
Browse files Browse the repository at this point in the history
  • Loading branch information
bergatco authored Sep 16, 2024
2 parents b0a4edb + 140a2a2 commit 02df50a
Show file tree
Hide file tree
Showing 4 changed files with 331 additions and 384 deletions.
6 changes: 2 additions & 4 deletions src/modules/feature/course-sync/EndCourseSyncDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
<p data-testid="end-course-sync-dialog-info-text">
{{
$t("feature-course-sync.EndCourseSyncDialog.description", {
courseName: courseName,
groupName: groupName,
courseName: courseName || "",
groupName: groupName || "",
})
}}
</p>
Expand All @@ -43,11 +43,9 @@ const isOpen = defineModel("isOpen", {
const props = defineProps({
courseName: {
type: String,
required: true,
},
groupName: {
type: String,
required: true,
},
courseId: {
type: String,
Expand Down
140 changes: 135 additions & 5 deletions src/pages/administration/RoomsOverview.page.unit.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { groupModule } from "@/store";
import AuthModule from "@/store/auth";
import EnvConfigModule from "@/store/env-config";
import { SortOrder } from "@/store/types/sort-order.enum";
Expand All @@ -11,16 +12,18 @@ import {
createTestingI18n,
createTestingVuetify,
} from "@@/tests/test-utils/setup";
import { useCourseApi, useCourseList } from "@data-room";
import {
EndCourseSyncDialog,
StartExistingCourseSyncDialog,
} from "@feature-course-sync";
import { createMock, DeepMocked } from "@golevelup/ts-jest";
import { mount, VueWrapper } from "@vue/test-utils";
import { nextTick, ref } from "vue";
import vueDompurifyHTMLPlugin from "vue-dompurify-html";
import { Router, useRoute, useRouter } from "vue-router";
import { VDataTableServer } from "vuetify/lib/components/index.mjs";
import { useCourseApi, useCourseList } from "@data-room";
import { groupModule } from "@/store";
import RoomsOverview from "./RoomsOverview.page.vue";
import { StartExistingCourseSyncDialog } from "@feature-course-sync";

jest.mock("vue-router", () => ({
useRoute: jest.fn(),
Expand Down Expand Up @@ -80,6 +83,7 @@ describe("RoomsOverview", () => {
},
stubs: {
StartExistingCourseSyncDialog: true,
EndCourseSyncDialog: true,
},
},
props: {
Expand Down Expand Up @@ -344,7 +348,7 @@ describe("RoomsOverview", () => {
};
};

it("should render 3 buttons", () => {
it("should render the edit, delete and start sync buttons", () => {
const { wrapper } = setup();

const editBtn = wrapper.find('[data-testid="course-table-edit-btn"]');
Expand All @@ -357,9 +361,61 @@ describe("RoomsOverview", () => {
'[data-testid="course-table-start-course-sync-btn"]'
);

const endSyncButton = wrapper.find(
'[data-testid="course-table-end-course-sync-btn"]'
);

expect(startSyncButton.exists()).toBeTruthy();
expect(editBtn.exists()).toBeTruthy();
expect(deleteBtn.exists()).toBeTruthy();
expect(endSyncButton.exists()).toBeFalsy();
});
});

describe("when synchronized courses are available", () => {
const setup = () => {
useCourseListMock.courses.value =
courseInfoDataResponseFactory.buildList(10, {
classNames: ["1A, 1B, 1C"],
teacherNames: ["Lehrer", "Vertretung", "Lehrer Mock"],
syncedGroup: "GroupName",
});

const envConfigModule = createModuleMocks(EnvConfigModule, {
getEnv: envsFactory.build({
FEATURE_SCHULCONNEX_COURSE_SYNC_ENABLED: true,
FEATURE_SHOW_NEW_ROOMS_VIEW_ENABLED: true,
}),
});

const { wrapper } = createWrapper("current", envConfigModule);

return {
wrapper,
};
};

it("should render the edit, delete and end sync buttons", () => {
const { wrapper } = setup();

const editBtn = wrapper.find('[data-testid="course-table-edit-btn"]');

const deleteBtn = wrapper.find(
'[data-testid="course-table-delete-btn"]'
);

const endSyncButton = wrapper.find(
'[data-testid="course-table-end-course-sync-btn"]'
);

const startSyncButton = wrapper.find(
'[data-testid="course-table-start-course-sync-btn"]'
);

expect(endSyncButton.exists()).toBeTruthy();
expect(editBtn.exists()).toBeTruthy();
expect(deleteBtn.exists()).toBeTruthy();
expect(startSyncButton.exists()).toBeFalsy();
});
});

Expand All @@ -385,7 +441,7 @@ describe("RoomsOverview", () => {
});
});

describe("when feature Schulconnex Sync is enabled", () => {
describe("when feature Schulconnex Sync is disabled", () => {
const setup = () => {
useCourseListMock.courses.value =
courseInfoDataResponseFactory.buildList(10, {
Expand Down Expand Up @@ -420,7 +476,12 @@ describe("RoomsOverview", () => {
'[data-testid="course-table-start-course-sync-btn"]'
);

const endSyncButton = wrapper.find(
'[data-testid="course-table-end-course-sync-btn"]'
);

expect(startSyncButton.element.id).toBeFalsy();
expect(endSyncButton.exists()).toBeFalsy();
expect(editBtn.exists()).toBeTruthy();
expect(deleteBtn.exists()).toBeTruthy();
});
Expand Down Expand Up @@ -520,6 +581,42 @@ describe("RoomsOverview", () => {
});
});

describe("when clicking on the end sync course button", () => {
const setup = () => {
useCourseListMock.courses.value = [
courseInfoDataResponseFactory.build({
classNames: ["1A, 1B, 1C"],
teacherNames: ["Lehrer", "Vertretung", "Lehrer Mock"],
syncedGroup: "GroupName",
}),
];

const { wrapper } = createWrapper("archive");

const courseId: string = useCourseListMock.courses.value[0].id;

return {
wrapper,
courseId,
};
};

it("should open the EndCourseSyncDialog ", async () => {
const { wrapper } = setup();

await wrapper
.find('[data-testid="course-table-end-course-sync-btn"]')
.trigger("click");
await nextTick();

const dialog = wrapper.findComponent({
name: "EndCourseSyncDialog",
});

expect(dialog.vm.isOpen).toBe(true);
});
});

describe("when delete dialog is open", () => {
const setup = () => {
useCourseListMock.courses.value = [
Expand Down Expand Up @@ -605,6 +702,39 @@ describe("RoomsOverview", () => {
expect(useCourseListMock.fetchCourses).toHaveBeenCalled();
});
});

describe("when end sync dialog emit succeed", () => {
const setup = () => {
useCourseListMock.courses.value = [
courseInfoDataResponseFactory.build({
classNames: ["1A, 1B, 1C"],
teacherNames: ["Lehrer", "Vertretung", "Lehrer Mock"],
syncedGroup: "GroupName",
}),
];

const { wrapper } = createWrapper();

return {
wrapper,
useCourseListMock,
};
};

it("should fetch courses", async () => {
const { wrapper } = setup();

await wrapper
.find('[data-testid="course-table-end-course-sync-btn"]')
.trigger("click");
await nextTick();

wrapper.getComponent(EndCourseSyncDialog).emitted("success");
await nextTick();

expect(useCourseListMock.fetchCourses).toHaveBeenCalled();
});
});
});

describe("tabs", () => {
Expand Down
49 changes: 45 additions & 4 deletions src/pages/administration/RoomsOverview.page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,21 @@
<v-icon>{{ mdiSync }}</v-icon>
</v-btn>
</template>
<template v-if="showEndSyncAction(item)">
<v-btn
v-if="courseSyncEnabled"
:title="t('feature-course-sync.EndCourseSyncDialog.title')"
:aria-label="t('feature-course-sync.EndCourseSyncDialog.title')"
data-testid="course-table-end-course-sync-btn"
variant="outlined"
size="small"
class="mx-1 px-1"
min-width="0"
@click="onClickEndSyncIcon(item)"
>
<v-icon>{{ mdiSyncOff }}</v-icon>
</v-btn>
</template>
</template>
</v-data-table-server>
<v-custom-dialog
Expand Down Expand Up @@ -114,6 +129,14 @@
data-testid="start-sync-dialog"
/>

<EndCourseSyncDialog
v-model:is-open="isEndSyncDialogOpen"
:course-name="selectedItem?.name"
:group-name="selectedItem?.syncedGroup"
:course-id="selectedItem?.id"
@success="loadCourseList"
/>

<v-btn
class="my-5 button-start"
color="primary"
Expand Down Expand Up @@ -154,13 +177,21 @@ import {
} from "@/utils/inject";
import { buildPageTitle } from "@/utils/pageTitle";
import { useCourseList } from "@data-room";
import { StartExistingCourseSyncDialog } from "@feature-course-sync";
import {
EndCourseSyncDialog,
StartExistingCourseSyncDialog,
} from "@feature-course-sync";
import { RenderHTML } from "@feature-render-html";
import {
mdiPencilOutline,
mdiSync,
mdiSyncOff,
mdiTrashCanOutline,
} from "@icons/material";
import { useTitle } from "@vueuse/core";
import { computed, ComputedRef, onMounted, PropType, ref, Ref } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute, useRouter } from "vue-router";
import { mdiPencilOutline, mdiSync, mdiTrashCanOutline } from "@icons/material";
type Tab = "current" | "archive";
Expand Down Expand Up @@ -245,10 +276,17 @@ const showRoomAction = (item: CourseInfoDataResponse) =>
const showSyncAction = (item: CourseInfoDataResponse) =>
hasPermission.value && !item.syncedGroup;
const showEndSyncAction = (item: CourseInfoDataResponse) =>
hasPermission.value && item.syncedGroup;
const isDeleteDialogOpen: Ref<boolean> = ref(false);
const isStartSyncDialogOpen: Ref<boolean> = ref(false);
const isCourseSyncDialogOpen: Ref<boolean> = ref(false);
const isEndSyncDialogOpen: Ref<boolean> = ref(false);
const selectedItem: Ref<CourseInfoDataResponse | undefined> = ref();
const selectedItemName: ComputedRef<string> = computed(
Expand All @@ -261,6 +299,11 @@ const onClickStartSyncIcon = (selectedCourse: CourseInfoDataResponse) => {
isCourseSyncDialogOpen.value = true;
};
const onClickEndSyncIcon = (selectedCourse: CourseInfoDataResponse) => {
selectedItem.value = selectedCourse;
isEndSyncDialogOpen.value = true;
};
const onClickDeleteIcon = (selectedCourse: CourseInfoDataResponse) => {
selectedItem.value = selectedCourse;
isDeleteDialogOpen.value = true;
Expand Down Expand Up @@ -372,8 +415,6 @@ const getInstituteTitle: ComputedRef<string> = computed(() => {
return "Dataport";
}
});
const isCourseSyncDialogOpen: Ref<boolean> = ref(false);
</script>

<style scoped>
Expand Down
Loading

0 comments on commit 02df50a

Please sign in to comment.