Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions src/main/java/edu/ksu/canvas/impl/AssignmentImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,23 @@ public Optional<Assignment> createAssignment(String courseId, Assignment assignm

@Override
public Optional<Assignment> deleteAssignment(String courseId, Integer assignmentId) throws IOException {
String url = buildCanvasUrl("courses/" + courseId + "/assignments/" + assignmentId, Collections.emptyMap());
return deleteAssignment(url);
}

@Override
public Optional<Assignment> deleteAssignment(String courseId, String assignmentId) throws IOException {
String url = buildCanvasUrl("courses/" + courseId + "/assignments/" + assignmentId, Collections.emptyMap());
return deleteAssignment(url);
}
Comment on lines +71 to +74
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new String-based deleteAssignment overload lacks test coverage. While the existing Integer-based deleteAssignment method also doesn't have explicit tests, this pattern follows the editAssignment methods which similarly lack explicit tests. However, given that this codebase has comprehensive test coverage for other writer operations (as seen in CalendarWriterUTest, CourseManagerUTest, etc.), consider adding test coverage for both delete methods to maintain consistency with other tested writer methods like createAssignment.

Copilot uses AI. Check for mistakes.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot open a new pull request to apply changes based on this feedback


private Optional<Assignment> deleteAssignment(String url) throws IOException {
Map<String, List<String>> postParams = new HashMap<>();
postParams.put("event", Collections.singletonList("delete"));
String createdUrl = buildCanvasUrl("courses/" + courseId + "/assignments/" + assignmentId, Collections.emptyMap());
Response response = canvasMessenger.deleteFromCanvas(oauthToken, createdUrl, postParams);
LOG.debug("response " + response.toString());
Response response = canvasMessenger.deleteFromCanvas(oauthToken, url, postParams);
LOG.debug("response {}", response);
if(response.getErrorHappened() || response.getResponseCode() != 200){
LOG.debug("Failed to delete assignment, error message: " + response.toString());
LOG.debug("Failed to delete assignment, error message: {}", response);
return Optional.empty();
}
return responseParser.parseToObject(Assignment.class, response);
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/edu/ksu/canvas/interfaces/AssignmentWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ public interface AssignmentWriter extends CanvasWriter<Assignment, AssignmentWri
*/
Optional<Assignment> deleteAssignment(String courseId, Integer assignmentId) throws IOException;

/**
* Deletes a specified assignment in Canvas. This overload allows us to pass assignment IDs that are non-numeric (e.g. "lti_context_id:ab84f579-4442-4d4a-acd8-85c5ec6fd2b6").
* @param courseId Course ID of course to delete assignment from
* @param assignmentId Assignment ID of assignment to delete
* @return The deleted Assignment object as returned by the Canvas API
* @throws IOException When there is an error communicating with Canvas
*/
Optional<Assignment> deleteAssignment(String courseId, String assignmentId) throws IOException;

/**
* Writes an Assignment object to the Canvas API
* @param courseId Course ID that this assignment is associated with
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package edu.ksu.canvas.tests.assignment;

import edu.ksu.canvas.CanvasTestBase;
import edu.ksu.canvas.impl.AssignmentImpl;
import edu.ksu.canvas.interfaces.AssignmentWriter;
import edu.ksu.canvas.model.assignment.Assignment;
import edu.ksu.canvas.net.FakeRestClient;
import junit.framework.AssertionFailedError;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Optional;

public class AssignmentWriterUTest extends CanvasTestBase {

@Autowired
private FakeRestClient fakeRestClient;
private AssignmentWriter assignmentWriter;

@Before
public void setupData() {
assignmentWriter = new AssignmentImpl(baseUrl, apiVersion, SOME_OAUTH_TOKEN, fakeRestClient, SOME_CONNECT_TIMEOUT, SOME_READ_TIMEOUT, DEFAULT_PAGINATION_PAGE_SIZE, false);
}

@Test
public void testDeleteAssignmentWithIntegerId() throws IOException {
String someCourseId = "1234";
Integer someAssignmentId = 123;
String url = baseUrl + "/api/v1/courses/" + someCourseId + "/assignments/" + someAssignmentId;
fakeRestClient.addSuccessResponse(url, "SampleJson/assignment/DeletedAssignment.json");
Optional<Assignment> deletedAssignmentOpt = assignmentWriter.deleteAssignment(someCourseId, someAssignmentId);
Assignment deletedAssignment = deletedAssignmentOpt.orElseThrow(AssertionFailedError::new);
Assert.assertEquals("Assignment1", deletedAssignment.getName());
Assert.assertEquals(Integer.valueOf(1), deletedAssignment.getId());
}

@Test
public void testDeleteAssignmentWithStringId() throws IOException {
String someCourseId = "1234";
String someAssignmentId = "lti_context_id:ab84f579-4442-4d4a-acd8-85c5ec6fd2b6";
String url = baseUrl + "/api/v1/courses/" + someCourseId + "/assignments/" + someAssignmentId;
fakeRestClient.addSuccessResponse(url, "SampleJson/assignment/DeletedAssignment.json");
Optional<Assignment> deletedAssignmentOpt = assignmentWriter.deleteAssignment(someCourseId, someAssignmentId);
Assignment deletedAssignment = deletedAssignmentOpt.orElseThrow(AssertionFailedError::new);
Assert.assertEquals("Assignment1", deletedAssignment.getName());
Assert.assertEquals(Integer.valueOf(1), deletedAssignment.getId());
}

@Test
public void testDeleteAssignmentWithNumericStringId() throws IOException {
String someCourseId = "1234";
String someAssignmentId = "456";
String url = baseUrl + "/api/v1/courses/" + someCourseId + "/assignments/" + someAssignmentId;
fakeRestClient.addSuccessResponse(url, "SampleJson/assignment/DeletedAssignment.json");
Optional<Assignment> deletedAssignmentOpt = assignmentWriter.deleteAssignment(someCourseId, someAssignmentId);
Assignment deletedAssignment = deletedAssignmentOpt.orElseThrow(AssertionFailedError::new);
Assert.assertEquals("Assignment1", deletedAssignment.getName());
Assert.assertEquals(Integer.valueOf(1), deletedAssignment.getId());
}
}
40 changes: 40 additions & 0 deletions src/test/resources/SampleJson/assignment/DeletedAssignment.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"id": 1,
"description": "",
"due_at": null,
"unlock_at": null,
"lock_at": null,
"points_possible": 30,
"grading_type": "points",
"assignment_group_id": 1967,
"grading_standard_id": null,
"created_at": "2016-10-28T19:37:50Z",
"updated_at": "2016-10-28T19:37:50Z",
"peer_reviews": false,
"automatic_peer_reviews": false,
"position": 1,
"grade_group_students_individually": false,
"anonymous_peer_reviews": false,
"group_category_id": null,
"post_to_sis": false,
"moderated_grading": false,
"omit_from_final_grade": false,
"course_id": 1146,
"name": "Assignment1",
"submission_types": [
"none"
],
"has_submitted_submissions": false,
"muted": false,
"html_url": "https://canvas.example.edu/courses/1146/assignments/316000",
"has_overrides": false,
"needs_grading_count": 0,
"integration_id": null,
"integration_data": {},
"published": false,
"unpublishable": true,
"only_visible_to_overrides": false,
"locked_for_user": false,
"submissions_download_url": "https://canvas.example.edu/courses/1146/assignments/316000/submissions?zip=1",
"workflow_state": "deleted"
}