From 42ce579eeea57d564c1fc601c29c034ff102261f Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Mon, 21 Jul 2025 14:11:46 -0600 Subject: [PATCH] adding github classroom links to settings --- .../local/assignment/localAssignment.ts | 4 + .../utils/assignmentMarkdownParser.ts | 20 +++- .../utils/assignmentMarkdownSerializer.ts | 9 +- .../local/tests/assignmentMarkdown.test.ts | 92 ++++++++++++++++--- 4 files changed, 108 insertions(+), 17 deletions(-) diff --git a/src/models/local/assignment/localAssignment.ts b/src/models/local/assignment/localAssignment.ts index e53745e..1abdfc6 100644 --- a/src/models/local/assignment/localAssignment.ts +++ b/src/models/local/assignment/localAssignment.ts @@ -17,6 +17,8 @@ export interface LocalAssignment extends IModuleItem { submissionTypes: AssignmentSubmissionType[]; allowedFileUploadExtensions: string[]; rubric: RubricItem[]; + githubClassroomAssignmentShareLink?: string; + githubClassroomAssignmentLink?: string; } export const zodLocalAssignment = z.object({ @@ -28,6 +30,8 @@ export const zodLocalAssignment = z.object({ submissionTypes: zodAssignmentSubmissionType.array(), allowedFileUploadExtensions: z.string().array(), rubric: zodRubricItem.array(), + githubClassroomAssignmentShareLink: z.string().optional(), + githubClassroomAssignmentLink: z.string().optional(), }); export const localAssignmentMarkdown = { diff --git a/src/models/local/assignment/utils/assignmentMarkdownParser.ts b/src/models/local/assignment/utils/assignmentMarkdownParser.ts index 2e4a6af..37cb068 100644 --- a/src/models/local/assignment/utils/assignmentMarkdownParser.ts +++ b/src/models/local/assignment/utils/assignmentMarkdownParser.ts @@ -52,6 +52,14 @@ const parseSettings = (input: string) => { const assignmentGroupName = extractLabelValue(input, "AssignmentGroupName"); const submissionTypes = parseSubmissionTypes(input); const fileUploadExtensions = parseFileUploadExtensions(input); + const githubClassroomAssignmentShareLink = extractLabelValue( + input, + "GithubClassroomAssignmentShareLink" + ); + const githubClassroomAssignmentLink = extractLabelValue( + input, + "GithubClassroomAssignmentLink" + ); const dueAt = verifyDateOrThrow(rawDueAt, "DueAt"); const lockAt = verifyDateStringOrUndefined(rawLockAt); @@ -62,6 +70,8 @@ const parseSettings = (input: string) => { fileUploadExtensions, dueAt, lockAt, + githubClassroomAssignmentShareLink, + githubClassroomAssignmentLink, }; }; @@ -111,12 +121,13 @@ export const assignmentMarkdownParser = { parseMarkdown(input: string, name: string): LocalAssignment { const settingsString = input.split("---")[0]; const { - // name, assignmentGroupName, submissionTypes, fileUploadExtensions, dueAt, lockAt, + githubClassroomAssignmentShareLink, + githubClassroomAssignmentLink, } = parseSettings(settingsString); const description = input @@ -139,6 +150,13 @@ export const assignmentMarkdownParser = { rubric: rubric, description: description, }; + if (githubClassroomAssignmentShareLink) { + assignment.githubClassroomAssignmentShareLink = + githubClassroomAssignmentShareLink; + } + if (githubClassroomAssignmentLink) { + assignment.githubClassroomAssignmentLink = githubClassroomAssignmentLink; + } return assignment; }, }; diff --git a/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts b/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts index 001f5f8..1bc3b5a 100644 --- a/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts +++ b/src/models/local/assignment/utils/assignmentMarkdownSerializer.ts @@ -25,15 +25,16 @@ const settingsToMarkdown = (assignment: LocalAssignment) => { .map((fileExtension: string) => `- ${fileExtension}`) .join("\n"); - const settingsMarkdown = [ + const settingsMarkdownArr = [ `LockAt: ${printableLockAt}`, `DueAt: ${printableDueDate}`, `AssignmentGroupName: ${assignment.localAssignmentGroupName}`, `SubmissionTypes:\n${submissionTypesMarkdown}`, `AllowedFileUploadExtensions:\n${allowedFileUploadExtensionsMarkdown}`, - ].join("\n"); - - return settingsMarkdown; + `GithubClassroomAssignmentShareLink: ${assignment.githubClassroomAssignmentShareLink ?? ""}`, + `GithubClassroomAssignmentLink: ${assignment.githubClassroomAssignmentLink ?? ""}`, + ]; + return settingsMarkdownArr.join("\n"); }; export const assignmentMarkdownSerializer = { diff --git a/src/models/local/tests/assignmentMarkdown.test.ts b/src/models/local/tests/assignmentMarkdown.test.ts index c5574b6..97f9834 100644 --- a/src/models/local/tests/assignmentMarkdown.test.ts +++ b/src/models/local/tests/assignmentMarkdown.test.ts @@ -46,8 +46,10 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); @@ -70,8 +72,10 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); @@ -94,8 +98,10 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); @@ -118,8 +124,10 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); @@ -139,8 +147,10 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); @@ -160,9 +170,67 @@ describe("AssignmentMarkdownTests", () => { const assignmentMarkdown = assignmentMarkdownSerializer.toMarkdown(assignment); - const parsedAssignment = - assignmentMarkdownParser.parseMarkdown(assignmentMarkdown, name); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); expect(parsedAssignment).toEqual(assignment); }); + + it("assignment with githubClassroomAssignmentShareLink and githubClassroomAssignmentLink can be parsed", () => { + const name = "test assignment"; + const assignment: LocalAssignment = { + name, + description: "here is the description", + dueAt: "08/21/2023 23:59:00", + lockAt: "08/21/2023 23:59:00", + submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], + localAssignmentGroupName: "Final Project", + rubric: [], + allowedFileUploadExtensions: [], + githubClassroomAssignmentShareLink: "https://github.com/share-link", + githubClassroomAssignmentLink: "https://github.com/assignment-link", + }; + + const assignmentMarkdown = + assignmentMarkdownSerializer.toMarkdown(assignment); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); + + expect(parsedAssignment.githubClassroomAssignmentShareLink).toEqual( + "https://github.com/share-link" + ); + expect(parsedAssignment.githubClassroomAssignmentLink).toEqual( + "https://github.com/assignment-link" + ); + expect(parsedAssignment).toEqual(assignment); + }); + + it("assignment without githubClassroomAssignmentShareLink and githubClassroomAssignmentLink can be parsed", () => { + const name = "test assignment"; + const assignment: LocalAssignment = { + name, + description: "here is the description", + dueAt: "08/21/2023 23:59:00", + lockAt: "08/21/2023 23:59:00", + submissionTypes: [AssignmentSubmissionType.ONLINE_UPLOAD], + localAssignmentGroupName: "Final Project", + rubric: [], + allowedFileUploadExtensions: [], + }; + + const assignmentMarkdown = + assignmentMarkdownSerializer.toMarkdown(assignment); + const parsedAssignment = assignmentMarkdownParser.parseMarkdown( + assignmentMarkdown, + name + ); + + expect(parsedAssignment.githubClassroomAssignmentShareLink).toBeUndefined(); + expect(parsedAssignment.githubClassroomAssignmentLink).toBeUndefined(); + expect(parsedAssignment).toEqual(assignment); + }); });