Skip to content
Open
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
1 change: 1 addition & 0 deletions src/main/java/edu/ksu/canvas/CanvasApiFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ private void setupClassMap() {
readerMap.put(CourseSettingsReader.class, CourseSettingsImpl.class);
readerMap.put(GradingStandardReader.class, GradingStandardImpl.class);
readerMap.put(ModuleReader.class, ModuleImpl.class);
readerMap.put(ModuleItemReader.class, ModuleItemImpl.class);
readerMap.put(SisImportReader.class, SisImportImpl.class);
readerMap.put(SelectiveDataReader.class, SelectiveDataImpl.class);
readerMap.put(MigrationIssueReader.class, MigrationIssueImpl.class);
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/edu/ksu/canvas/impl/ModuleItemImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package edu.ksu.canvas.impl;

import com.google.gson.reflect.TypeToken;
import edu.ksu.canvas.interfaces.CanvasWriter;
import edu.ksu.canvas.interfaces.ModuleItemReader;
import edu.ksu.canvas.model.ModuleItem;
import edu.ksu.canvas.net.RestClient;
import edu.ksu.canvas.oauth.OauthToken;
import edu.ksu.canvas.requestOptions.ListModuleItemsOptions;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

public class ModuleItemImpl extends BaseImpl<ModuleItem, ModuleItemReader, CanvasWriter> implements ModuleItemReader {
private static final Logger LOG = LoggerFactory.getLogger(ModuleItemImpl.class);
public ModuleItemImpl(final String canvasBaseUrl, final Integer apiVersion, final OauthToken oauthToken, final RestClient restClient, final int connectTimeout, final int readTimeout, final Integer paginationPageSize, final Boolean serializeNulls) {
super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, paginationPageSize, serializeNulls);
}

@Override
public List<ModuleItem> getModuleItemsInModule(final ListModuleItemsOptions options) throws IOException {
LOG.debug("Retrieving items for module {}", options.getModuleId());
String url = buildCanvasUrl(String.format("courses/%d/modules/%d/items", options.getCourseId(), options.getModuleId()), options.getOptionsMap());
return getListFromCanvas(url);
}

@Override
protected Type listType() {
return new TypeToken<List<ModuleItem>>() {
}.getType();
}

@Override
protected Class<ModuleItem> objectType() {
return ModuleItem.class;
}
}
18 changes: 18 additions & 0 deletions src/main/java/edu/ksu/canvas/interfaces/ModuleItemReader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package edu.ksu.canvas.interfaces;

import edu.ksu.canvas.model.ModuleItem;
import edu.ksu.canvas.requestOptions.ListModuleItemsOptions;

import java.io.IOException;
import java.util.List;

public interface ModuleItemReader extends CanvasReader<ModuleItem, ModuleItemReader> {
/**
* Retrieve the list of items in a module.
*
* @param options The object holding options for this API call
* @return List of the items in a module
* @throws IOException When there is an error communicating with Canvas
*/
public List<ModuleItem> getModuleItemsInModule(ListModuleItemsOptions options) throws IOException;
}
162 changes: 162 additions & 0 deletions src/main/java/edu/ksu/canvas/model/ModuleItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
package edu.ksu.canvas.model;

import java.io.Serializable;

/* https://canvas.instructure.com/doc/api/modules.html#ModuleItem */
public class ModuleItem extends BaseCanvasModel implements Serializable {
private Long id;
private Long moduleId;
private Long position;
private String title;
private Long indent;
private String type;
private Long contentId;
private String htmlUrl;
private String url; /* optional */
private String pageUrl; /* only for 'Page' type */
private String externalUrl; /* only for 'ExternalUrl' and 'ExternalTool' types */
private Boolean newTab; /* only for 'ExternalTool' type */
private CompletionRequirement completionRequirement;
private Boolean published;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Long getModuleId() {
return moduleId;
}

public void setModuleId(Long moduleId) {
this.moduleId = moduleId;
}

public Long getPosition() {
return position;
}

public void setPosition(Long position) {
this.position = position;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public Long getIndent() {
return indent;
}

public void setIndent(Long indent) {
this.indent = indent;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public long getContentId() {
return contentId;
}

public void setContenId(long contentId) {
this.contentId = contentId;
}

public String getHtmlUrl() {
return htmlUrl;
}

public void setHtmlUrl(String htmlUrl) {
this.htmlUrl = htmlUrl;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getPageUrl() {
return pageUrl;
}

public void setPageUrl(String pageUrl) {
this.pageUrl = pageUrl;
}

public String getExternalUrl() {
return externalUrl;
}

public void setExternalUrl(String externalUrl) {
this.externalUrl = externalUrl;
}

public java.lang.Boolean getNewTab() {
return newTab;
}

public void setNewTab(java.lang.Boolean newTab) {
this.newTab = newTab;
}

public CompletionRequirement getCompletionRequirement() {
return completionRequirement;
}

public void setCompletionRequirement(CompletionRequirement completionRequirement) {
this.completionRequirement = completionRequirement;
}

public Boolean getPublished() {
return published;
}

public void setPublished(Boolean published) {
this.published = published;
}

public class CompletionRequirement extends BaseCanvasModel implements Serializable {
private String type;
private java.math.BigDecimal minScore;
private Boolean completed;

public java.math.BigDecimal getMinScore() {
return minScore;
}

public void setMinScore(java.math.BigDecimal minScore) {
this.minScore = minScore;
}

public Boolean getCompleted() {
return completed;
}

public void setCompleted(Boolean completed) {
this.completed = completed;
}

public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package edu.ksu.canvas.requestOptions;

import java.util.List;

/**
* Options for listing the items in a module.
*
* @see <a href="https://canvas.instructure.com/doc/api/modules.html#method.context_module_items_api.index">List module items</a>
*/
public class ListModuleItemsOptions extends BaseOptions {

public enum Include {
CONTENT_DETAILS
}

private Long courseId;

private Long moduleId;

public ListModuleItemsOptions(Long courseId, Long moduleId) {
this.courseId = courseId;
this.moduleId = moduleId;
}

public Long getCourseId() {
return courseId;
}

public Long getModuleId() {
return moduleId;
}

public ListModuleItemsOptions includes(List<Include> includes) {
addEnumList("include[]", includes);
return this;
}

public ListModuleItemsOptions searchTerm(String searchTerm) {
addSingleItem("search_term", searchTerm);
return this;
}

public ListModuleItemsOptions studentId(String studentId) {
addSingleItem("student_id", studentId);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package edu.ksu.canvas.tests.module;

import edu.ksu.canvas.CanvasTestBase;
import edu.ksu.canvas.impl.ModuleItemImpl;
import edu.ksu.canvas.interfaces.ModuleItemReader;
import edu.ksu.canvas.model.ModuleItem;
import edu.ksu.canvas.net.FakeRestClient;
import edu.ksu.canvas.requestOptions.ListModuleItemsOptions;
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.List;

public class ModuleItemListingTest extends CanvasTestBase {
@Autowired
private FakeRestClient fakeRestClient;
private ModuleItemReader moduleItemReader;

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

@Test
public void testListModuleItemsInModule() throws IOException {
Long courseId = 1092L;
Long moduleId = 1059720L;
ListModuleItemsOptions options = new ListModuleItemsOptions(courseId, moduleId);
String url = baseUrl + "/api/v1/courses/1092/modules/1059720/items";

fakeRestClient.addSuccessResponse(url, "SampleJson/ModuleItems.json");
List<ModuleItem> moduleItems = moduleItemReader.getModuleItemsInModule(options);
Assert.assertNotNull(moduleItems);
Assert.assertEquals(4, moduleItems.size());
for (ModuleItem moduleItem: moduleItems) { /* Copied from https://github.com/instructure/CanvasAPI/blob/develop/src/test/java/ModuleItemUnitTest.java */
Assert.assertTrue(moduleItem.getId() > 0);
Assert.assertNotNull(moduleItem.getType());
Assert.assertNotNull(moduleItem.getTitle());
Assert.assertNotNull(moduleItem.getHtmlUrl());
Assert.assertNotNull(moduleItem.getUrl());
if (moduleItem.getCompletionRequirement() != null) {
Assert.assertNotNull(moduleItem.getCompletionRequirement().getType());
}
}
}
}
63 changes: 63 additions & 0 deletions src/test/resources/SampleJson/ModuleItems.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[
{
"id": 9012239,
"indent": 0,
"position": 1,
"title": "Android 101",
"type": "Assignment",
"module_id": 1059720,
"html_url": "https://mobiledev.instructure.com/courses/833052/modules/items/9012239",
"content_id": 2241839,
"url": "https://mobiledev.instructure.com/api/v1/courses/833052/assignments/2241839",
"completion_requirement": {
"type": "must_submit",
"completed": true
}
},
{
"id": 9012244,
"indent": 0,
"position": 2,
"title": "Favorite App Video",
"type": "Assignment",
"module_id": 1059720,
"html_url": "https://mobiledev.instructure.com/courses/833052/modules/items/9012244",
"content_id": 2241864,
"url": "https://mobiledev.instructure.com/api/v1/courses/833052/assignments/2241864",
"completion_requirement": {
"type": "min_score",
"min_score": "5",
"completed": true
}
},
{
"id": 9012248,
"indent": 0,
"position": 3,
"title": "Android vs. iOS",
"type": "Discussion",
"module_id": 1059720,
"html_url": "https://mobiledev.instructure.com/courses/833052/modules/items/9012248",
"content_id": 1369942,
"url": "https://mobiledev.instructure.com/api/v1/courses/833052/discussion_topics/1369942",
"completion_requirement": {
"type": "must_contribute",
"completed": false
}
},
{
"id": 9012251,
"indent": 0,
"position": 4,
"title": "Easy Quiz",
"type": "Quiz",
"module_id": 1059720,
"html_url": "https://mobiledev.instructure.com/courses/833052/modules/items/9012251",
"content_id": 757314,
"url": "https://mobiledev.instructure.com/api/v1/courses/833052/quizzes/757314",
"completion_requirement": {
"type": "must_submit",
"completed": true
}
}
]