+
{{ $t("group.no_members_found") }}
@@ -104,4 +105,13 @@ const amountOfMembers = computed(() => {
const { mutateAsync: removeStudent } = useRemoveUserFromGroupMutation();
-
+
diff --git a/frontend/src/views/GroupsView.vue b/frontend/src/views/GroupsView.vue
index 5bf7fd4f..6a3dd797 100644
--- a/frontend/src/views/GroupsView.vue
+++ b/frontend/src/views/GroupsView.vue
@@ -4,13 +4,14 @@
{{ $t("group.error") }}
{{ "Project: " + project!.name }}
+
+
- {{ $t("group.groups") }}
+ {{ $t("group.groups") }}
{{ $t("group.members") }}
- {{ $t("group.actions") }}
+ {{ $t("group.actions") }}
-
{{ $t("group.not_found2") }}
-
{{ $t("group.create_group") }}
+
{{
+ $t("group.create_group")
+ }}
@@ -35,11 +38,11 @@
import { useCreateGroupsMutation, useProjectGroupsQuery } from "@/queries/Group";
import { computed, toRefs } from "vue";
import { useProjectQuery } from "@/queries/Project";
-import GroupCard from "@/components/home/cards/GroupCard.vue";
+import GroupCard from "@/components/groups/GroupCard.vue";
import { useCurrentUserQuery } from "@/queries/User";
import { type GroupForm } from "@/models/Group";
import { useSubjectInstructorsQuery, useSubjectStudentsQuery } from "@/queries/Subject";
-import AllstudentsDialog from "@/components/AllstudentsDialog.vue";
+import StudentsDialog from "@/components/groups/StudentsDialog.vue";
const props = defineProps<{
projectId: number;
@@ -116,10 +119,19 @@ async function createGroup() {
diff --git a/frontend/tests/components/buttons/GroupButtons.spec.ts b/frontend/tests/components/buttons/GroupButtons.spec.ts
new file mode 100644
index 00000000..146685fb
--- /dev/null
+++ b/frontend/tests/components/buttons/GroupButtons.spec.ts
@@ -0,0 +1,162 @@
+import {mount} from "@vue/test-utils";
+import {expect, describe, it, vi} from "vitest";
+import GroupButtons from "@/components/buttons/GroupButtons.vue"
+import {ref} from "vue";
+
+const mockGroup = {
+ members: [
+ {uid: "student1"}
+ ],
+ team_name: "testgroep"
+}
+
+const mockMembers = [
+ {uid: "student1"}
+]
+
+const mockProject = {
+ capacity: 3
+}
+
+const mockUser = {
+ uid: "user"
+}
+
+const testUserGroupsQuery = {
+ data: ref([
+ {project_id: 1, id: 1}
+ ])
+}
+
+vi.mock('@/queries/Group', () => ({
+ useUserGroupsQuery: vi.fn(() => testUserGroupsQuery),
+ useLeaveGroupUserMutation: vi.fn(() => vi.fn()),
+ useJoinGroupUserMutation: vi.fn(() => vi.fn()),
+ useDeleteGroupMutation: vi.fn(() => vi.fn()),
+}))
+
+
+describe("GroupButtons", () => {
+ it("function isUserInGroup should be true", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: {uid: "student1"},
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const isUserInGroupFunction = (wrapper.vm as any).isUserInGroup;
+ expect(isUserInGroupFunction).toBe(true)
+ })
+ it("function isUserInGroup should be false", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: {uid: "student2"},
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const isUserInGroupFunction = (wrapper.vm as any).isUserInGroup;
+ expect(isUserInGroupFunction).toBe(false)
+ });
+
+ it("function isUserInAnotherGroup should be true", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: {id: 2, members: mockMembers},
+ project: {id: 1},
+ user: mockUser,
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const isUserInAnotherGroupFunction = (wrapper.vm as any).isUserInAnotherGroup
+ expect(isUserInAnotherGroupFunction).toBe(true);
+ });
+ it("function isUserInAnotherGroup should be false", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: {id: 1, members: mockMembers},
+ project: {id: 1},
+ user: mockUser,
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const isUserInAnotherGroupFunction = (wrapper.vm as any).isUserInAnotherGroup
+ expect(isUserInAnotherGroupFunction).toBe(false)
+ });
+
+ it("function canLeaveGroup should be True and render", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: {capacity: 3},
+ user: {uid: "student1"},
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const canLeaveGroupFunction = (wrapper.vm as any).canLeaveGroup
+ expect(canLeaveGroupFunction).toBe(true)
+ expect(wrapper.text()).toContain("Verlaten")
+ });
+ it("function canLeaveGroup should be False", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: {capacity: 1},
+ user: {uid: "student1"},
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const canLeaveGroupFunction = (wrapper.vm as any).canLeaveGroup
+ expect(canLeaveGroupFunction).toBe(false)
+ });
+
+ it("function canJoinGroup should be True and render", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: {capacity: 2, id: 2},
+ user: {uid: "student2"},
+ amountOfMembers: 1,
+ isTeacher: false,
+ }
+ })
+ const canJoinGroupFunction = (wrapper.vm as any).canJoinGroup
+ expect(canJoinGroupFunction).toBe(true)
+ expect(wrapper.text()).toContain("Aansluiten")
+ });
+ it("function canJoinGroup should be false", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: {capacity: 2, id: 2},
+ user: {uid: "student2"},
+ amountOfMembers: 2,
+ isTeacher: false,
+ }
+ })
+ const canJoinGroupFunction = (wrapper.vm as any).canJoinGroup
+ expect(canJoinGroupFunction).toBe(false)
+ });
+
+ it("render if user is teacher", () => {
+ const wrapper = mount(GroupButtons, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: mockUser,
+ amountOfMembers: 2,
+ isTeacher: true,
+ }
+ })
+ expect(wrapper.text()).toContain("Groep verwijderen")
+ });
+});
diff --git a/frontend/tests/components/groups/GroupCard.spec.ts b/frontend/tests/components/groups/GroupCard.spec.ts
new file mode 100644
index 00000000..45ea074c
--- /dev/null
+++ b/frontend/tests/components/groups/GroupCard.spec.ts
@@ -0,0 +1,85 @@
+import {mount} from "@vue/test-utils";
+import {expect, describe, it, vi} from "vitest";
+import GroupCard from "@/components/groups/GroupCard.vue"
+
+vi.mock("@/components/groups/StudentsDialog.vue", () => ({
+ default: {
+ template: "
",
+ },
+}));
+
+vi.mock("@/components/buttons/GroupButtons.vue", () => ({
+ default: {
+ template: "
",
+ },
+}));
+
+const mockGroup = {
+ members: [
+ {uid: "student1"}
+ ],
+ team_name: "testgroep"
+}
+
+const mockProject = {
+ capacity: 3
+}
+
+const mockUser = {
+ uid: "user"
+}
+
+describe("GroupCard", () => {
+ it("render group card", () => {
+ const wrapper = mount(GroupCard, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: mockUser,
+ isTeacher: false,
+ }
+
+ })
+ expect(wrapper.findComponent(".studentsDialog").exists()).toBeTruthy()
+ expect(wrapper.text()).toContain("1/3")
+ });
+ it("render as student", () => {
+ const wrapper = mount(GroupCard, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: mockUser,
+ isTeacher: false,
+ }
+
+ })
+ expect(wrapper.findComponent({name: "VBtn"}).exists()).toBeFalsy()
+ });
+ it("render as teacher", () => {
+ const wrapper = mount(GroupCard, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: mockUser,
+ isTeacher: true,
+ }
+
+ })
+ const button = wrapper.findComponent({name: "VBtn"})
+ expect(button.exists()).toBeTruthy()
+ expect(button.text()).toContain("Naar groepspagina")
+ });
+ it("function amountOfMembers", () => {
+ const wrapper = mount(GroupCard, {
+ props: {
+ group: mockGroup,
+ project: mockProject,
+ user: mockUser,
+ isTeacher: false,
+ }
+
+ })
+ const amountOfMembersFunction = (wrapper.vm as any).amountOfMembers;
+ expect(amountOfMembersFunction).toBe(1)
+ })
+});
diff --git a/frontend/tests/components/groups/StudentsDialog.spec.ts b/frontend/tests/components/groups/StudentsDialog.spec.ts
new file mode 100644
index 00000000..86570099
--- /dev/null
+++ b/frontend/tests/components/groups/StudentsDialog.spec.ts
@@ -0,0 +1,19 @@
+import {mount} from "@vue/test-utils";
+import {expect, describe, it} from "vitest";
+import StudentsDialog from "@/components/groups/StudentsDialog.vue"
+
+const mockStudents = [
+ {id: 1}
+]
+
+describe("StudentsDialog", () => {
+ const wrapper = mount(StudentsDialog, {
+ props: {
+ students: mockStudents,
+ title: "dialog title"
+ }
+ })
+ it("renders title", () => {
+ expect(wrapper.text()).toContain("dialog title")
+ });
+});
diff --git a/frontend/tests/views/GroupsView.spec.ts b/frontend/tests/views/GroupsView.spec.ts
new file mode 100644
index 00000000..90155d26
--- /dev/null
+++ b/frontend/tests/views/GroupsView.spec.ts
@@ -0,0 +1,131 @@
+import {mount} from "@vue/test-utils";
+import {expect, describe, it, vi} from "vitest";
+import GroupsView from "@/views/GroupsView.vue"
+import {ref} from "vue";
+
+const mockProject = {
+ name: "testproject"
+}
+
+const mockGroups = [
+ {id: 1, team_name: "Group 1"}
+]
+
+const mockUser = {
+ uid: "student",
+ setUid(value){
+ this.uid = value;
+ }
+}
+
+const mockInstructors = [
+ {uid: "teacher"}
+]
+
+const testProjectQuery = {
+ data: mockProject,
+ isLoading: ref(true),
+ isError: ref(true),
+ setIsError(value){
+ this.isError.value = value;
+ },
+ setIsLoading(value){
+ this.isLoading.value = value;
+ }
+};
+
+vi.mock('@/queries/Project', () => ({
+ useProjectQuery: vi.fn(() => testProjectQuery),
+}));
+
+const testProjectGroupsQuery = {
+ data: mockGroups,
+ isLoading: ref(false),
+ isError: ref(false),
+};
+
+const testCreateGroupsMutation = {
+ mutateAsync: vi.fn()
+}
+
+vi.mock('@/queries/Group', () => ({
+ useProjectGroupsQuery: vi.fn(() => testProjectGroupsQuery),
+ useCreateGroupsMutation: vi.fn(() => testCreateGroupsMutation)
+}))
+
+const testCurrentUserQuery ={
+ data: ref(mockUser),
+ isLoading: ref(false),
+ isError: ref(false),
+}
+
+vi.mock('@/queries/User', () => ({
+ useCurrentUserQuery: vi.fn(() => testCurrentUserQuery),
+}))
+
+const testSubjectStudentsQuery ={
+ isLoading: ref(false),
+ isError: ref(false),
+}
+
+const testSubjectInstructorsQuery ={
+ data: ref(mockInstructors),
+ isLoading: ref(false),
+ isError: ref(false),
+}
+
+vi.mock('@/queries/Subject', () => ({
+ useSubjectStudentsQuery: vi.fn(() => testSubjectStudentsQuery),
+ useSubjectInstructorsQuery: vi.fn(() => testSubjectInstructorsQuery),
+}))
+
+vi.mock("@/components/groups/StudentsDialog.vue", () => ({
+ default: {
+ template: "
",
+ },
+}));
+
+vi.mock("@/components/groups/GroupCard.vue", () => ({
+ default: {
+ template: "
",
+ },
+}));
+
+describe("GroupsView", () => {
+ const wrapper = mount(GroupsView, {
+ props: {
+ projectId: 1
+ }
+ });
+
+ it("render if loading", () => {
+ expect(wrapper.text()).toContain("Aan het laden...")
+ });
+
+ it("render if error", async () => {
+ testProjectQuery.setIsLoading(false)
+ await wrapper.vm.$nextTick();
+ expect(wrapper.text()).toContain("Fout bij het laden van de pagina")
+ });
+
+ it("render groupsview", async () => {
+ testProjectQuery.setIsError(false)
+ await wrapper.vm.$nextTick();
+ const text = wrapper.text()
+ expect(text).toContain("Project: testproject")
+ expect(wrapper.findComponent(".studentsDialog").exists()).toBeTruthy()
+ expect(wrapper.findComponent(".groupCard").exists()).toBeTruthy()
+ });
+
+ it("render if user is student", () => {
+ expect(wrapper.findComponent({name: "VBtn"}).exists()).toBeFalsy()
+ });
+
+ it("render if user is teacher", async () => {
+ testCurrentUserQuery.data.value.setUid("teacher")
+ await wrapper.vm.$nextTick();
+ const button = wrapper.findComponent({name: "VBtn"})
+ expect(button.exists()).toBeTruthy()
+ expect(button.text()).toContain("Nieuwe groep")
+ });
+})