mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
centralizing logic
This commit is contained in:
@@ -8,25 +8,10 @@ export const GET = async (
|
|||||||
}: { params: { courseName: string; moduleName: string } }
|
}: { params: { courseName: string; moduleName: string } }
|
||||||
) =>
|
) =>
|
||||||
await withErrorHandling(async () => {
|
await withErrorHandling(async () => {
|
||||||
const names = await fileStorageService.assignments.getAssignmentNames(
|
const assignments = await fileStorageService.assignments.getAssignments(
|
||||||
courseName,
|
courseName,
|
||||||
moduleName
|
moduleName
|
||||||
);
|
);
|
||||||
const assignments = (
|
|
||||||
await Promise.all(
|
|
||||||
names.map(async (name) => {
|
|
||||||
try {
|
|
||||||
return await fileStorageService.assignments.getAssignment(
|
|
||||||
courseName,
|
|
||||||
moduleName,
|
|
||||||
name
|
|
||||||
);
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).filter((a) => a !== null);
|
|
||||||
|
|
||||||
return Response.json(assignments);
|
return Response.json(assignments);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export interface LocalAssignment extends IModuleItem {
|
|||||||
rubric: RubricItem[];
|
rubric: RubricItem[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export const localAssignmentMarkdown = {
|
export const localAssignmentMarkdown = {
|
||||||
parseMarkdown: assignmentMarkdownParser.parseMarkdown,
|
parseMarkdown: assignmentMarkdownParser.parseMarkdown,
|
||||||
toMarkdown: assignmentMarkdownSerializer.toMarkdown,
|
toMarkdown: assignmentMarkdownSerializer.toMarkdown,
|
||||||
|
|||||||
@@ -6,37 +6,44 @@ import { assignmentMarkdownSerializer } from "@/models/local/assignment/utils/as
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
|
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
|
import { courseItemFileStorageService } from "./courseItemFileStorageService";
|
||||||
|
|
||||||
|
const getAssignmentNames = async (courseName: string, moduleName: string) => {
|
||||||
|
const filePath = path.join(basePath, courseName, moduleName, "assignments");
|
||||||
|
if (!(await directoryOrFileExists(filePath))) {
|
||||||
|
console.log(
|
||||||
|
`Error loading course by name, assignments folder does not exist in ${filePath}`
|
||||||
|
);
|
||||||
|
await fs.mkdir(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const assignmentFiles = await fs.readdir(filePath);
|
||||||
|
return assignmentFiles.map((f) => f.replace(/\.md$/, ""));
|
||||||
|
};
|
||||||
|
const getAssignment = async (
|
||||||
|
courseName: string,
|
||||||
|
moduleName: string,
|
||||||
|
assignmentName: string
|
||||||
|
) => {
|
||||||
|
const filePath = path.join(
|
||||||
|
basePath,
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
"assignments",
|
||||||
|
assignmentName + ".md"
|
||||||
|
);
|
||||||
|
const rawFile = (await fs.readFile(filePath, "utf-8")).replace(/\r\n/g, "\n");
|
||||||
|
return localAssignmentMarkdown.parseMarkdown(rawFile);
|
||||||
|
};
|
||||||
export const assignmentsFileStorageService = {
|
export const assignmentsFileStorageService = {
|
||||||
async getAssignmentNames(courseName: string, moduleName: string) {
|
getAssignmentNames,
|
||||||
const filePath = path.join(basePath, courseName, moduleName, "assignments");
|
getAssignment,
|
||||||
if (!(await directoryOrFileExists(filePath))) {
|
async getAssignments(courseName: string, moduleName: string) {
|
||||||
console.log(
|
return await courseItemFileStorageService.getItems(
|
||||||
`Error loading course by name, assignments folder does not exist in ${filePath}`
|
|
||||||
);
|
|
||||||
await fs.mkdir(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const assignmentFiles = await fs.readdir(filePath);
|
|
||||||
return assignmentFiles.map((f) => f.replace(/\.md$/, ""));
|
|
||||||
},
|
|
||||||
async getAssignment(
|
|
||||||
courseName: string,
|
|
||||||
moduleName: string,
|
|
||||||
assignmentName: string
|
|
||||||
) {
|
|
||||||
const filePath = path.join(
|
|
||||||
basePath,
|
|
||||||
courseName,
|
courseName,
|
||||||
moduleName,
|
moduleName,
|
||||||
"assignments",
|
"Assignment"
|
||||||
assignmentName + ".md"
|
|
||||||
);
|
);
|
||||||
const rawFile = (await fs.readFile(filePath, "utf-8")).replace(
|
|
||||||
/\r\n/g,
|
|
||||||
"\n"
|
|
||||||
);
|
|
||||||
return localAssignmentMarkdown.parseMarkdown(rawFile);
|
|
||||||
},
|
},
|
||||||
async updateOrCreateAssignment({
|
async updateOrCreateAssignment({
|
||||||
courseName,
|
courseName,
|
||||||
@@ -74,7 +81,6 @@ export const assignmentsFileStorageService = {
|
|||||||
moduleName: string;
|
moduleName: string;
|
||||||
assignmentName: string;
|
assignmentName: string;
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
const filePath = path.join(
|
const filePath = path.join(
|
||||||
basePath,
|
basePath,
|
||||||
courseName,
|
courseName,
|
||||||
@@ -83,6 +89,6 @@ export const assignmentsFileStorageService = {
|
|||||||
assignmentName + ".md"
|
assignmentName + ".md"
|
||||||
);
|
);
|
||||||
console.log("removing assignment", filePath);
|
console.log("removing assignment", filePath);
|
||||||
await fs.unlink(filePath)
|
await fs.unlink(filePath);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
102
nextjs/src/services/fileStorage/courseItemFileStorageService.ts
Normal file
102
nextjs/src/services/fileStorage/courseItemFileStorageService.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import path from "path";
|
||||||
|
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
|
||||||
|
import fs from "fs/promises";
|
||||||
|
import {
|
||||||
|
LocalAssignment,
|
||||||
|
localAssignmentMarkdown,
|
||||||
|
} from "@/models/local/assignment/localAssignment";
|
||||||
|
import {
|
||||||
|
LocalQuiz,
|
||||||
|
localQuizMarkdownUtils,
|
||||||
|
} from "@/models/local/quiz/localQuiz";
|
||||||
|
import {
|
||||||
|
LocalCoursePage,
|
||||||
|
localPageMarkdownUtils,
|
||||||
|
} from "@/models/local/page/localCoursePage";
|
||||||
|
|
||||||
|
const typeToFolder = {
|
||||||
|
Assignment: "assignments",
|
||||||
|
Quiz: "quizzes",
|
||||||
|
Page: "pages",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type CourseItemType = "Assignment" | "Quiz" | "Page";
|
||||||
|
|
||||||
|
const getItemFileNames = async (
|
||||||
|
courseName: string,
|
||||||
|
moduleName: string,
|
||||||
|
type: CourseItemType
|
||||||
|
) => {
|
||||||
|
const folder = typeToFolder[type];
|
||||||
|
const filePath = path.join(basePath, courseName, moduleName, folder);
|
||||||
|
if (!(await directoryOrFileExists(filePath))) {
|
||||||
|
console.log(
|
||||||
|
`Error loading ${type}, ${folder} folder does not exist in ${filePath}`
|
||||||
|
);
|
||||||
|
await fs.mkdir(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const itemFiles = await fs.readdir(filePath);
|
||||||
|
return itemFiles.map((f) => f.replace(/\.md$/, ""));
|
||||||
|
};
|
||||||
|
type CourseItemReturnType<T extends CourseItemType> = T extends "Assignment"
|
||||||
|
? LocalAssignment
|
||||||
|
: T extends "Quiz"
|
||||||
|
? LocalQuiz
|
||||||
|
: LocalCoursePage;
|
||||||
|
|
||||||
|
const getItem = async <T extends CourseItemType>(
|
||||||
|
courseName: string,
|
||||||
|
moduleName: string,
|
||||||
|
name: string,
|
||||||
|
type: T
|
||||||
|
): Promise<CourseItemReturnType<T>> => {
|
||||||
|
const folder = typeToFolder[type];
|
||||||
|
const filePath = path.join(
|
||||||
|
basePath,
|
||||||
|
courseName,
|
||||||
|
moduleName,
|
||||||
|
folder,
|
||||||
|
name + ".md"
|
||||||
|
);
|
||||||
|
const rawFile = (await fs.readFile(filePath, "utf-8")).replace(/\r\n/g, "\n");
|
||||||
|
if (type === "Assignment") {
|
||||||
|
return localAssignmentMarkdown.parseMarkdown(
|
||||||
|
rawFile
|
||||||
|
) as CourseItemReturnType<T>;
|
||||||
|
} else if (type === "Quiz") {
|
||||||
|
return localQuizMarkdownUtils.parseMarkdown(
|
||||||
|
rawFile
|
||||||
|
) as CourseItemReturnType<T>;
|
||||||
|
} else if (type === "Page") {
|
||||||
|
return localPageMarkdownUtils.parseMarkdown(
|
||||||
|
rawFile
|
||||||
|
) as CourseItemReturnType<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw Error(`cannot read item, invalid type: ${type} in ${filePath}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const courseItemFileStorageService = {
|
||||||
|
getItem,
|
||||||
|
getItems: async <T extends CourseItemType>(
|
||||||
|
courseName: string,
|
||||||
|
moduleName: string,
|
||||||
|
type: T
|
||||||
|
): Promise<CourseItemReturnType<T>[]> => {
|
||||||
|
const fileNames = await getItemFileNames(courseName, moduleName, type);
|
||||||
|
const items = (
|
||||||
|
await Promise.all(
|
||||||
|
fileNames.map(async (name) => {
|
||||||
|
try {
|
||||||
|
const item = await getItem(courseName, moduleName, name, type);
|
||||||
|
return item;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).filter((a) => a !== null);
|
||||||
|
return items;
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,36 +1,23 @@
|
|||||||
import { localPageMarkdownUtils, LocalCoursePage } from "@/models/local/page/localCoursePage";
|
import {
|
||||||
|
localPageMarkdownUtils,
|
||||||
|
LocalCoursePage,
|
||||||
|
} from "@/models/local/page/localCoursePage";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
|
import { basePath } from "./utils/fileSystemUtils";
|
||||||
|
import { courseItemFileStorageService } from "./courseItemFileStorageService";
|
||||||
|
|
||||||
export const pageFileStorageService = {
|
export const pageFileStorageService = {
|
||||||
async getPageNames(courseName: string, moduleName: string) {
|
getPage: async (courseName: string, moduleName: string, name: string) =>
|
||||||
const filePath = path.join(basePath, courseName, moduleName, "pages");
|
await courseItemFileStorageService.getItem(
|
||||||
if (!(await directoryOrFileExists(filePath))) {
|
|
||||||
console.log(
|
|
||||||
`Error loading course by name, pages folder does not exist in ${filePath}`
|
|
||||||
);
|
|
||||||
await fs.mkdir(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = await fs.readdir(filePath);
|
|
||||||
return files.map((f) => f.replace(/\.md$/, ""));
|
|
||||||
},
|
|
||||||
|
|
||||||
async getPage(courseName: string, moduleName: string, pageName: string) {
|
|
||||||
const filePath = path.join(
|
|
||||||
basePath,
|
|
||||||
courseName,
|
courseName,
|
||||||
moduleName,
|
moduleName,
|
||||||
"pages",
|
name,
|
||||||
pageName + ".md"
|
"Page"
|
||||||
);
|
),
|
||||||
const rawFile = (await fs.readFile(filePath, "utf-8")).replace(
|
getPages: async (courseName: string, moduleName: string) =>
|
||||||
/\r\n/g,
|
await courseItemFileStorageService.getItems(courseName, moduleName, "Page"),
|
||||||
"\n"
|
|
||||||
);
|
|
||||||
return localPageMarkdownUtils.parseMarkdown(rawFile);
|
|
||||||
},
|
|
||||||
async updatePage(
|
async updatePage(
|
||||||
courseName: string,
|
courseName: string,
|
||||||
moduleName: string,
|
moduleName: string,
|
||||||
@@ -82,6 +69,6 @@ export const pageFileStorageService = {
|
|||||||
pageName + ".md"
|
pageName + ".md"
|
||||||
);
|
);
|
||||||
console.log("removing page", filePath);
|
console.log("removing page", filePath);
|
||||||
await fs.unlink(filePath)
|
await fs.unlink(filePath);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,60 +1,23 @@
|
|||||||
import {
|
import {
|
||||||
localQuizMarkdownUtils,
|
|
||||||
LocalQuiz,
|
LocalQuiz,
|
||||||
} from "@/models/local/quiz/localQuiz";
|
} from "@/models/local/quiz/localQuiz";
|
||||||
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
|
import { quizMarkdownUtils } from "@/models/local/quiz/utils/quizMarkdownUtils";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { basePath, directoryOrFileExists } from "./utils/fileSystemUtils";
|
import { basePath } from "./utils/fileSystemUtils";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
|
import { courseItemFileStorageService } from "./courseItemFileStorageService";
|
||||||
|
|
||||||
const getQuizNames = async (courseName: string, moduleName: string) => {
|
|
||||||
const filePath = path.join(basePath, courseName, moduleName, "quizzes");
|
|
||||||
if (!(await directoryOrFileExists(filePath))) {
|
|
||||||
console.log(
|
|
||||||
`Error loading course by name, quiz folder does not exist in ${filePath}`
|
|
||||||
);
|
|
||||||
await fs.mkdir(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const files = await fs.readdir(filePath);
|
|
||||||
return files.map((f) => f.replace(/\.md$/, ""));
|
|
||||||
};
|
|
||||||
|
|
||||||
const getQuiz = async (
|
|
||||||
courseName: string,
|
|
||||||
moduleName: string,
|
|
||||||
quizName: string
|
|
||||||
) => {
|
|
||||||
const filePath = path.join(
|
|
||||||
basePath,
|
|
||||||
courseName,
|
|
||||||
moduleName,
|
|
||||||
"quizzes",
|
|
||||||
quizName + ".md"
|
|
||||||
);
|
|
||||||
const rawFile = (await fs.readFile(filePath, "utf-8")).replace(/\r\n/g, "\n");
|
|
||||||
return localQuizMarkdownUtils.parseMarkdown(rawFile);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const quizFileStorageService = {
|
export const quizFileStorageService = {
|
||||||
getQuizNames,
|
getQuiz: async (courseName: string, moduleName: string, quizName: string) =>
|
||||||
getQuiz,
|
await courseItemFileStorageService.getItem(
|
||||||
async getQuizzes(courseName: string, moduleName: string) {
|
courseName,
|
||||||
const fileNames = await getQuizNames(courseName, moduleName);
|
moduleName,
|
||||||
const quizzes = (
|
quizName,
|
||||||
await Promise.all(
|
"Quiz"
|
||||||
fileNames.map(async (name) => {
|
),
|
||||||
try {
|
getQuizzes: async (courseName: string, moduleName: string) =>
|
||||||
return await getQuiz(courseName, moduleName, name);
|
await courseItemFileStorageService.getItems(courseName, moduleName, "Quiz"),
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
).filter((a) => a !== null);
|
|
||||||
|
|
||||||
return quizzes;
|
|
||||||
},
|
|
||||||
|
|
||||||
async updateQuiz(
|
async updateQuiz(
|
||||||
courseName: string,
|
courseName: string,
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import path from "path";
|
|
||||||
import { describe, it, expect, beforeEach } from "vitest";
|
import { describe, it, expect, beforeEach } from "vitest";
|
||||||
import { promises as fs } from "fs";
|
import { promises as fs } from "fs";
|
||||||
import {
|
import {
|
||||||
DayOfWeek,
|
DayOfWeek,
|
||||||
LocalCourse,
|
|
||||||
LocalCourseSettings,
|
LocalCourseSettings,
|
||||||
} from "@/models/local/localCourse";
|
} from "@/models/local/localCourse";
|
||||||
import { QuestionType } from "@/models/local/quiz/localQuizQuestion";
|
|
||||||
import { fileStorageService } from "../fileStorage/fileStorageService";
|
import { fileStorageService } from "../fileStorage/fileStorageService";
|
||||||
import { basePath } from "../fileStorage/utils/fileSystemUtils";
|
|
||||||
|
|
||||||
describe("FileStorageTests", () => {
|
describe("FileStorageTests", () => {
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -55,52 +51,4 @@ describe("FileStorageTests", () => {
|
|||||||
|
|
||||||
expect(moduleNames).toContain(moduleName);
|
expect(moduleNames).toContain(moduleName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("invalid quizzes do not get loaded", async () => {
|
|
||||||
const courseName = "testCourse";
|
|
||||||
const moduleName = "testModule";
|
|
||||||
const validQuizMarkdown = `Name: validQuiz
|
|
||||||
LockAt: 08/28/2024 23:59:00
|
|
||||||
DueAt: 08/28/2024 23:59:00
|
|
||||||
Password:
|
|
||||||
ShuffleAnswers: true
|
|
||||||
ShowCorrectAnswers: false
|
|
||||||
OneQuestionAtATime: false
|
|
||||||
AssignmentGroup: Assignments
|
|
||||||
AllowedAttempts: -1
|
|
||||||
Description: Repeat this quiz until you can complete it without notes/help.
|
|
||||||
---
|
|
||||||
Points: 0.25
|
|
||||||
|
|
||||||
An empty string is
|
|
||||||
|
|
||||||
a) truthy
|
|
||||||
*b) falsy
|
|
||||||
`;
|
|
||||||
const invalidQuizMarkdown = "name: testQuiz\n---\nnot a quiz";
|
|
||||||
await fileStorageService.createCourseFolderForTesting(courseName);
|
|
||||||
await fileStorageService.modules.createModule(courseName, moduleName);
|
|
||||||
|
|
||||||
await fs.mkdir(`${basePath}/${courseName}/${moduleName}/quizzes`, {
|
|
||||||
recursive: true,
|
|
||||||
});
|
|
||||||
await fs.writeFile(
|
|
||||||
`${basePath}/${courseName}/${moduleName}/quizzes/testQuiz.md`,
|
|
||||||
invalidQuizMarkdown
|
|
||||||
);
|
|
||||||
await fs.writeFile(
|
|
||||||
`${basePath}/${courseName}/${moduleName}/quizzes/validQuiz.md`,
|
|
||||||
validQuizMarkdown
|
|
||||||
);
|
|
||||||
|
|
||||||
const quizzes = await fileStorageService.quizzes.getQuizzes(
|
|
||||||
courseName,
|
|
||||||
moduleName
|
|
||||||
);
|
|
||||||
const quizNames = quizzes.map((q) => q.name);
|
|
||||||
|
|
||||||
expect(quizNames).not.includes("testQuiz");
|
|
||||||
expect(quizNames).include("validQuiz");
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
167
nextjs/src/services/tests/fileStorageParsingErrors.test.ts
Normal file
167
nextjs/src/services/tests/fileStorageParsingErrors.test.ts
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
import { describe, it, expect, beforeEach } from "vitest";
|
||||||
|
import { promises as fs } from "fs";
|
||||||
|
import { fileStorageService } from "../fileStorage/fileStorageService";
|
||||||
|
import { basePath } from "../fileStorage/utils/fileSystemUtils";
|
||||||
|
|
||||||
|
describe("FileStorageTests", () => {
|
||||||
|
beforeEach(async () => {
|
||||||
|
const storageDirectory =
|
||||||
|
process.env.STORAGE_DIRECTORY ?? "/tmp/canvasManagerTests";
|
||||||
|
try {
|
||||||
|
await fs.access(storageDirectory);
|
||||||
|
await fs.rm(storageDirectory, { recursive: true });
|
||||||
|
} catch (error) {}
|
||||||
|
await fs.mkdir(storageDirectory, { recursive: true });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("invalid quizzes do not get loaded", async () => {
|
||||||
|
const courseName = "testCourse";
|
||||||
|
const moduleName = "testModule";
|
||||||
|
const validQuizMarkdown = `Name: validQuiz
|
||||||
|
LockAt: 08/28/2024 23:59:00
|
||||||
|
DueAt: 08/28/2024 23:59:00
|
||||||
|
Password:
|
||||||
|
ShuffleAnswers: true
|
||||||
|
ShowCorrectAnswers: false
|
||||||
|
OneQuestionAtATime: false
|
||||||
|
AssignmentGroup: Assignments
|
||||||
|
AllowedAttempts: -1
|
||||||
|
Description: Repeat this quiz until you can complete it without notes/help.
|
||||||
|
---
|
||||||
|
Points: 0.25
|
||||||
|
|
||||||
|
An empty string is
|
||||||
|
|
||||||
|
a) truthy
|
||||||
|
*b) falsy
|
||||||
|
`;
|
||||||
|
const invalidQuizMarkdown = "name: testQuiz\n---\nnot a quiz";
|
||||||
|
await fileStorageService.createCourseFolderForTesting(courseName);
|
||||||
|
await fileStorageService.modules.createModule(courseName, moduleName);
|
||||||
|
|
||||||
|
await fs.mkdir(`${basePath}/${courseName}/${moduleName}/quizzes`, {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/quizzes/testQuiz.md`,
|
||||||
|
invalidQuizMarkdown
|
||||||
|
);
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/quizzes/validQuiz.md`,
|
||||||
|
validQuizMarkdown
|
||||||
|
);
|
||||||
|
|
||||||
|
const quizzes = await fileStorageService.quizzes.getQuizzes(
|
||||||
|
courseName,
|
||||||
|
moduleName
|
||||||
|
);
|
||||||
|
const quizNames = quizzes.map((q) => q.name);
|
||||||
|
|
||||||
|
expect(quizNames).not.includes("testQuiz");
|
||||||
|
expect(quizNames).include("validQuiz");
|
||||||
|
});
|
||||||
|
|
||||||
|
// it("invalid quizes give error messages", async () => {
|
||||||
|
// const courseName = "testCourse";
|
||||||
|
// const moduleName = "testModule";
|
||||||
|
// const invalidQuizMarkdown = "name: testQuiz\n---\nnot a quiz";
|
||||||
|
// await fileStorageService.createCourseFolderForTesting(courseName);
|
||||||
|
// await fileStorageService.modules.createModule(courseName, moduleName);
|
||||||
|
|
||||||
|
// await fs.mkdir(`${basePath}/${courseName}/${moduleName}/quizzes`, {
|
||||||
|
// recursive: true,
|
||||||
|
// });
|
||||||
|
// await fs.writeFile(
|
||||||
|
// `${basePath}/${courseName}/${moduleName}/quizzes/testQuiz.md`,
|
||||||
|
// invalidQuizMarkdown
|
||||||
|
// );
|
||||||
|
|
||||||
|
// const invalidReasons = await fileStorageService.quizzes.getInvalidQuizzes(
|
||||||
|
// courseName,
|
||||||
|
// moduleName
|
||||||
|
// );
|
||||||
|
// const invalidQuiz = invalidReasons.filter((q) => q.quizName === "testQuiz");
|
||||||
|
|
||||||
|
// expect(invalidQuiz.reason).is("testQuiz");
|
||||||
|
// });
|
||||||
|
|
||||||
|
it("invalid assignments dont get loaded", async () => {
|
||||||
|
const courseName = "testCourse";
|
||||||
|
const moduleName = "testModule";
|
||||||
|
const validAssignmentMarkdown = `Name: testAssignment
|
||||||
|
LockAt: 09/19/2024 23:59:00
|
||||||
|
DueAt: 09/19/2024 23:59:00
|
||||||
|
AssignmentGroupName: Assignments
|
||||||
|
SubmissionTypes:
|
||||||
|
- online_text_entry
|
||||||
|
- online_upload
|
||||||
|
AllowedFileUploadExtensions:
|
||||||
|
- pdf
|
||||||
|
---
|
||||||
|
description
|
||||||
|
## Rubric
|
||||||
|
- 2pts: animation has at least 5 transition states
|
||||||
|
`;
|
||||||
|
const invalidAssignment = "name: invalidAssignment\n---\nnot an assignment";
|
||||||
|
await fileStorageService.createCourseFolderForTesting(courseName);
|
||||||
|
await fileStorageService.modules.createModule(courseName, moduleName);
|
||||||
|
|
||||||
|
await fs.mkdir(`${basePath}/${courseName}/${moduleName}/assignments`, {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/assignments/testAssignment.md`,
|
||||||
|
validAssignmentMarkdown
|
||||||
|
);
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/assignments/invalidAssignment.md`,
|
||||||
|
invalidAssignment
|
||||||
|
);
|
||||||
|
|
||||||
|
const assignments = await fileStorageService.assignments.getAssignments(
|
||||||
|
courseName,
|
||||||
|
moduleName
|
||||||
|
);
|
||||||
|
const assignmentNames = assignments.map((q) => q.name);
|
||||||
|
|
||||||
|
expect(assignmentNames).not.includes("invalidAssignment");
|
||||||
|
expect(assignmentNames).include("testAssignment");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("invalid pages dont get loaded", async () => {
|
||||||
|
const courseName = "testCourse";
|
||||||
|
const moduleName = "testModule";
|
||||||
|
const validPageMarkdown = `Name: validPage
|
||||||
|
DueDateForOrdering: 08/31/2024 23:59:00
|
||||||
|
---
|
||||||
|
# Deploying React
|
||||||
|
`;
|
||||||
|
const invalidPageMarkdown = `Name: invalidPage
|
||||||
|
DueDateFo59:00
|
||||||
|
---
|
||||||
|
# Deploying React`;
|
||||||
|
await fileStorageService.createCourseFolderForTesting(courseName);
|
||||||
|
await fileStorageService.modules.createModule(courseName, moduleName);
|
||||||
|
|
||||||
|
await fs.mkdir(`${basePath}/${courseName}/${moduleName}/pages`, {
|
||||||
|
recursive: true,
|
||||||
|
});
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/pages/validPage.md`,
|
||||||
|
validPageMarkdown
|
||||||
|
);
|
||||||
|
await fs.writeFile(
|
||||||
|
`${basePath}/${courseName}/${moduleName}/pages/invalidPage.md`,
|
||||||
|
invalidPageMarkdown
|
||||||
|
);
|
||||||
|
|
||||||
|
const pages = await fileStorageService.pages.getPages(
|
||||||
|
courseName,
|
||||||
|
moduleName
|
||||||
|
);
|
||||||
|
const assignmentNames = pages.map((q) => q.name);
|
||||||
|
|
||||||
|
expect(assignmentNames).include("validPage");
|
||||||
|
expect(assignmentNames).not.includes("invalidPage");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user