DndServices boardFrom function fixed, its test written

This commit is contained in:
Hikmet 2023-08-05 22:03:41 +03:00
parent ab31222823
commit a2bac1666c
3 changed files with 75 additions and 24 deletions

View File

@ -1,13 +1,10 @@
import { ViewModel } from "../model/view_model";
import { useEffect, useRef, useState } from "react";
import { stopDragging } from "@/lib/utils/dnd_setting/dnd_service";
import { useEffect, useState } from "react";
import IDraggable from "@/lib/utils/dnd_setting/draggable";
import IActivity from "@/lib/activity/activity";
import IReply from "@/lib/exercise/reply";
import * as ExerciseServices from "@/lib/exercise/exercise_services";
import IBlank from "@/lib/utils/dnd_setting/blank";
import { nanoid } from "nanoid";
import IAnswer from "@/lib/exercise/answer";
import * as DndService from "@/lib/utils/dnd_setting/dnd_service";
export function useViewModel(
activityData: IActivity,
@ -21,14 +18,6 @@ export function useViewModel(
const [dndBoard, setDndBoard] = useState<IDraggable[]>();
const [replies, setReplies] = useState<IReply[]>();
const boardFrom = (exerciseAnswers: IAnswer[], replies: IReply[]) => {
const idBlackList = replies
.filter((r) => r.value !== null && r.value !== undefined)
.map((e) => e.id);
const board = exerciseAnswers.filter((a) => !idBlackList.includes(a.id));
return board.map((e) => ({ ...e, id: nanoid() }));
};
useEffect(() => {
const { replies, beenSolved } = ExerciseServices.getUltimateReplies(
activityData.id,
@ -37,7 +26,7 @@ export function useViewModel(
);
setReplies(replies);
setIsSolved(beenSolved);
setDndBoard(boardFrom(activityData.exercise.answers, replies));
setDndBoard(DndService.boardFrom(activityData.exercise, replies));
}, [activityData]);
const handleStartDragging = (item: { id: string; value: string }) => {
@ -48,7 +37,7 @@ export function useViewModel(
action: { type: "on-space" } | { type: "on-blank"; blankId: string }
) => {
if (!dndBoard || !replies || !dndDraggedItem) return;
const { board, blanks, draggedItem } = stopDragging(
const { board, blanks, draggedItem } = DndService.stopDragging(
{
board: dndBoard,
blanks: replies,
@ -81,7 +70,7 @@ export function useViewModel(
);
setIsSolved(false);
setReplies(newReplies);
setDndBoard(boardFrom(activityData.exercise.answers, newReplies));
setDndBoard(DndService.boardFrom(activityData.exercise, newReplies));
};
return {

View File

@ -1,7 +1,8 @@
import { stopDragging } from "./dnd_service";
import IFillInBlanksExercise from "@/lib/exercise/fill_in_blanks_exercise/fill_in_blanks_exercise";
import * as DndService from "./dnd_service";
describe("dnd_service module", () => {
describe("stopDragging function", () => {
describe("stopDragging()", () => {
const board = [
{ id: "1", value: "A" },
{ id: "2", value: "B" },
@ -14,7 +15,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BOARD dropped on an EMPTY BLANK", () => {
const draggedItem = { id: "1", value: "A" };
const action = { type: "on-blank", blankId: "9" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -28,7 +29,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BOARD dropped on an OCCUPIED BLANK", () => {
const draggedItem = { id: "1", value: "A" };
const action = { type: "on-blank", blankId: "8" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -45,7 +46,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BLANKS dropped on the SAME BLANK", () => {
const draggedItem = { id: "8", value: "D" };
const action = { type: "on-blank", blankId: "8" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -62,7 +63,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BLANKS dropped on a DIFFERENT BLANK", () => {
const draggedItem = { id: "8", value: "D" };
const action = { type: "on-blank", blankId: "7" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -80,7 +81,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BOARD dropped on SPACE", () => {
const draggedItem = { id: "1", value: "A" };
const action = { type: "on-space" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -97,7 +98,7 @@ describe("dnd_service module", () => {
test("case item picked FROM BLANKS dropped on SPACE", () => {
const draggedItem = { id: "8", value: "D" };
const action = { type: "on-space" };
const dndSetting = stopDragging(
const dndSetting = DndService.stopDragging(
{ board, blanks, draggedItem },
action as any
);
@ -113,4 +114,44 @@ describe("dnd_service module", () => {
]);
});
});
describe("boardFrom()", () => {
const sampleFillInBlanksExercise = {
type: "fill-in-blanks-exercise",
answers: [
{ id: "1B", value: "are" },
{ id: "2B", value: "is" },
{ id: "2D", value: "going?" },
],
template: [
{
id: "1",
atoms: [
{ id: "1A", type: "text", value: "How" },
{ id: "1B", type: "blank" },
{ id: "1C", type: "text", value: "you?" },
],
},
{
id: "2",
atoms: [
{ id: "2A", type: "text", value: "Where" },
{ id: "2B", type: "blank" },
{ id: "2C", type: "text", value: "he" },
{ id: "2D", type: "text" },
],
},
],
} as IFillInBlanksExercise;
const sampleReplies = [
{ id: "1B", value: null },
{ id: "2B", value: "is" },
{ id: "2D", value: "are" },
];
const board = DndService.boardFrom(
sampleFillInBlanksExercise,
sampleReplies
);
expect(board).toStrictEqual([{ id: expect.anything(), value: "going?" }]);
});
});

View File

@ -2,6 +2,9 @@ import { nanoid } from "nanoid";
import DndSetting from "./dnd_setting";
import IDraggable from "./draggable";
import IBlank from "./blank";
import IExercise from "@/lib/exercise/exercise";
import IReply from "@/lib/exercise/reply";
import IAnswer from "@/lib/exercise/answer";
/**
* DnD Serice assumes:
* - There is a board that contains items with certain values
@ -70,3 +73,21 @@ export const stopDragging = (
draggedItem: null,
};
};
export const boardFrom = (
exercise: IExercise,
replies: IReply[]
): IAnswer[] => {
const valueBlacklist = replies
.filter((r) => r.value !== null && r.value !== undefined)
.map((e) => e.value as string);
const board = valueBlacklist.reduce(
(acc, cur) => {
const index = acc.findIndex((e) => e.value === cur);
if (index === -1) return acc;
return acc.filter((e, i) => i !== index);
},
[...exercise.answers]
);
return board.map((e) => ({ ...e, id: nanoid() }));
};