├── .classpath ├── .github └── workflows │ └── maven.yml ├── .gitignore ├── .project ├── CONTRIBUTING.md ├── Jenkinsfile ├── License.txt ├── README.md ├── integration-example.properties ├── pom.xml └── src ├── integration-test └── java │ └── edu │ └── ksu │ └── canvas │ ├── calendar │ ├── CalendarIT.java │ ├── CourseUploadIT.java │ └── FeatureFlagIT.java │ └── contentMigration │ └── ContentMigrationIT.java ├── main └── java │ └── edu │ └── ksu │ └── canvas │ ├── CanvasApiFactory.java │ ├── TestLauncher.java │ ├── annotation │ ├── CanvasField.java │ └── CanvasObject.java │ ├── constants │ └── CanvasConstants.java │ ├── enums │ ├── SectionIncludes.java │ └── package-info.java │ ├── errors │ ├── ErrorDetails.java │ ├── ErrorHandler.java │ ├── GenericErrorHandler.java │ ├── GenericErrorResponse.java │ ├── UserErrorHandler.java │ └── UserErrorResponse.java │ ├── exception │ ├── CanvasException.java │ ├── InvalidOauthTokenException.java │ ├── ObjectNotFoundException.java │ ├── RateLimitException.java │ ├── RetriableException.java │ ├── ThrottlingException.java │ ├── UnauthorizedException.java │ └── package-info.java │ ├── impl │ ├── AccountImpl.java │ ├── AccountReportImpl.java │ ├── AccountReportSummaryImpl.java │ ├── AdminImpl.java │ ├── AssignmentGroupImpl.java │ ├── AssignmentImpl.java │ ├── AssignmentOverrideImpl.java │ ├── AuthenticationLogImpl.java │ ├── BaseImpl.java │ ├── CalendarEventImpl.java │ ├── CommunicationChannelImpl.java │ ├── ContentMigrationImpl.java │ ├── ConversationImpl.java │ ├── CourseImpl.java │ ├── CourseSettingsImpl.java │ ├── EnrollmentImpl.java │ ├── EnrollmentTermImpl.java │ ├── ExternalToolImpl.java │ ├── FeatureFlagImpl.java │ ├── FeatureImpl.java │ ├── FileImpl.java │ ├── GradingStandardImpl.java │ ├── GsonResponseParser.java │ ├── LoginImpl.java │ ├── MigrationIssueImpl.java │ ├── ModuleImpl.java │ ├── PageImpl.java │ ├── ProgressImpl.java │ ├── QuizImpl.java │ ├── QuizQuestionImpl.java │ ├── QuizSubmissionImpl.java │ ├── QuizSubmissionQuestionImpl.java │ ├── RestCanvasMessenger.java │ ├── RoleImpl.java │ ├── RubricImpl.java │ ├── SectionsImpl.java │ ├── SelectiveDataImpl.java │ ├── SisImportImpl.java │ ├── SubmissionImpl.java │ ├── TabImpl.java │ ├── UserImpl.java │ └── package-info.java │ ├── interfaces │ ├── AccountReader.java │ ├── AccountReportReader.java │ ├── AccountReportSummaryReader.java │ ├── AccountReportSummaryWriter.java │ ├── AccountReportWriter.java │ ├── AccountWriter.java │ ├── AdminReader.java │ ├── AdminWriter.java │ ├── AssignmentGroupReader.java │ ├── AssignmentGroupWriter.java │ ├── AssignmentOverrideReader.java │ ├── AssignmentOverrideWriter.java │ ├── AssignmentReader.java │ ├── AssignmentWriter.java │ ├── AuthenticationLogReader.java │ ├── CalendarReader.java │ ├── CalendarWriter.java │ ├── CanvasMessenger.java │ ├── CanvasReader.java │ ├── CanvasWriter.java │ ├── CommunicationChannelReader.java │ ├── CommunicationChannelWriter.java │ ├── ContentMigrationReader.java │ ├── ContentMigrationWriter.java │ ├── ConversationReader.java │ ├── ConversationWriter.java │ ├── CourseReader.java │ ├── CourseSettingsReader.java │ ├── CourseSettingsWriter.java │ ├── CourseWriter.java │ ├── EnrollmentReader.java │ ├── EnrollmentTermReader.java │ ├── EnrollmentTermWriter.java │ ├── EnrollmentWriter.java │ ├── ExternalToolReader.java │ ├── ExternalToolWriter.java │ ├── FeatureFlagReader.java │ ├── FeatureFlagWriter.java │ ├── FeatureReader.java │ ├── FeatureWriter.java │ ├── FileReader.java │ ├── FileWriter.java │ ├── GradingStandardReader.java │ ├── GradingStandardWriter.java │ ├── LoginReader.java │ ├── LoginWriter.java │ ├── MigrationIssueReader.java │ ├── ModuleReader.java │ ├── PageReader.java │ ├── PageWriter.java │ ├── ProgressReader.java │ ├── ProgressWriter.java │ ├── QuizQuestionReader.java │ ├── QuizQuestionWriter.java │ ├── QuizReader.java │ ├── QuizSubmissionQuestionReader.java │ ├── QuizSubmissionQuestionWriter.java │ ├── QuizSubmissionReader.java │ ├── QuizSubmissionWriter.java │ ├── QuizWriter.java │ ├── ResponseParser.java │ ├── RoleReader.java │ ├── RoleWriter.java │ ├── RubricReader.java │ ├── RubricWriter.java │ ├── SectionReader.java │ ├── SectionWriter.java │ ├── SelectiveDataReader.java │ ├── SisImportReader.java │ ├── SisImportWriter.java │ ├── SubmissionReader.java │ ├── SubmissionWriter.java │ ├── TabReader.java │ ├── TabWriter.java │ ├── UserReader.java │ ├── UserWriter.java │ └── package-info.java │ ├── model │ ├── Account.java │ ├── AccountAdmin.java │ ├── AuthenticationLog.java │ ├── BaseCanvasModel.java │ ├── CalendarEvent.java │ ├── CommunicationChannel.java │ ├── ContentMigration.java │ ├── Conversation.java │ ├── Course.java │ ├── CourseSettings.java │ ├── Deposit.java │ ├── Enrollment.java │ ├── EnrollmentTerm.java │ ├── ExternalTool.java │ ├── Feature.java │ ├── FeatureFlag.java │ ├── File.java │ ├── Grade.java │ ├── GradingStandard.java │ ├── Login.java │ ├── MigrationIssue.java │ ├── Module.java │ ├── Page.java │ ├── Progress.java │ ├── Role.java │ ├── Section.java │ ├── SelectiveData.java │ ├── SisImport.java │ ├── Tab.java │ ├── User.java │ ├── UserDisplay.java │ ├── assignment │ │ ├── Assignment.java │ │ ├── AssignmentDate.java │ │ ├── AssignmentGroup.java │ │ ├── AssignmentOverride.java │ │ ├── GradingRules.java │ │ ├── LockInfo.java │ │ ├── MediaComment.java │ │ ├── Quiz.java │ │ ├── QuizAnswer.java │ │ ├── QuizPermission.java │ │ ├── QuizQuestion.java │ │ ├── QuizSubmission.java │ │ ├── QuizSubmissionQuestion.java │ │ ├── QuizSubmissionResponse.java │ │ ├── Rubric.java │ │ ├── RubricAssessment.java │ │ ├── RubricAssociation.java │ │ ├── RubricCriterion.java │ │ ├── RubricRating.java │ │ ├── RubricSettings.java │ │ ├── Submission.java │ │ └── SubmissionComment.java │ ├── package-info.java │ ├── report │ │ ├── AccountReport.java │ │ ├── AccountReportAttachment.java │ │ └── AccountReportSummary.java │ ├── status │ │ ├── CanvasErrorResponse.java │ │ ├── Conclude.java │ │ ├── Delete.java │ │ └── package-info.java │ └── wrapper │ │ ├── EnrollmentTermWrapper.java │ │ ├── QuizSubmissionQuestionWrapper.java │ │ ├── QuizSubmissionWrapper.java │ │ └── package-info.java │ ├── net │ ├── ApiPost.java │ ├── RefreshingRestClient.java │ ├── Response.java │ ├── RestClient.java │ ├── SimpleRestClient.java │ └── package-info.java │ ├── oauth │ ├── NonRefreshableOauthToken.java │ ├── OauthToken.java │ ├── OauthTokenRefresher.java │ ├── RefreshableOauthToken.java │ ├── TokenRefreshResponse.java │ └── package-info.java │ ├── requestOptions │ ├── AccountReportOptions.java │ ├── AddMessageToConversationOptions.java │ ├── AnswerQuizQuestionOptions.java │ ├── BaseOptions.java │ ├── CompleteQuizSubmissionOptions.java │ ├── CreateCommunicationChannelOptions.java │ ├── CreateContentMigrationOptions.java │ ├── CreateConversationOptions.java │ ├── CreateCourseContentMigrationOptions.java │ ├── CreateSisImportOptions.java │ ├── CreateUserOptions.java │ ├── DeleteAssignmentGroupOptions.java │ ├── DeleteCalendarEventOptions.java │ ├── DeleteCourseOptions.java │ ├── GetAssignmentGroupOptions.java │ ├── GetEnrollmentOptions.java │ ├── GetEnrollmentTermOptions.java │ ├── GetQuizQuestionsOptions.java │ ├── GetQuizSubmissionsOptions.java │ ├── GetRubricOptions.java │ ├── GetSelectiveDataOptions.java │ ├── GetSingleAssignmentOptions.java │ ├── GetSingleConversationOptions.java │ ├── GetSingleCourseOptions.java │ ├── GetSubAccountsOptions.java │ ├── GetSubmissionsOptions.java │ ├── GetUsersInAccountOptions.java │ ├── GetUsersInCourseOptions.java │ ├── ListAccountAdminsOptions.java │ ├── ListAccountOptions.java │ ├── ListActiveCoursesInAccountOptions.java │ ├── ListAssignmentGroupOptions.java │ ├── ListCalendarEventsOptions.java │ ├── ListCourseAssignmentsOptions.java │ ├── ListCurrentUserCoursesOptions.java │ ├── ListExternalToolsOptions.java │ ├── ListModulesOptions.java │ ├── ListRolesOptions.java │ ├── ListUserAssignmentOptions.java │ ├── ListUserCoursesOptions.java │ ├── MultipleSubmissionsOptions.java │ ├── StartQuizSubmissionOptions.java │ ├── UnEnrollOptions.java │ ├── UpdateCourseTabOptions.java │ ├── UploadOptions.java │ └── package-info.java │ └── util │ ├── CanvasURLBuilder.java │ ├── HttpParameterBuilder.java │ ├── KeyFirstComparator.java │ └── package-info.java └── test ├── java └── edu │ └── ksu │ └── canvas │ ├── ApiFactoryUTest.java │ ├── BaseCanvasModelUTest.java │ ├── BaseImplUTest.java │ ├── CanvasTestBase.java │ ├── EnrollmentTermUTest.java │ ├── EnrollmentUTest.java │ ├── LocalServerTestBase.java │ ├── TestCanvasReader.java │ ├── TestCanvasReaderImpl.java │ ├── TestCanvasWriter.java │ ├── config │ ├── BaseTestConfig.java │ └── CommonTestConfig.java │ ├── errors │ └── ErrorsJsonTest.java │ ├── impl │ ├── GsonResponseParserInstantTest.java │ └── SubmissionImplTest.java │ ├── model │ ├── CalendarEventTest.java │ └── TestCanvasModel.java │ ├── net │ ├── FakeRestClient.java │ ├── RefreshingRestClientUTest.java │ └── SimpleRestClientUTest.java │ ├── oauth │ ├── OauthTokenRefresherUTest.java │ └── RefreshableTokenUTest.java │ ├── tests │ ├── account │ │ └── AccountReaderUTest.java │ ├── accountReport │ │ └── AccountReportUTest.java │ ├── accountReportSummary │ │ └── AccountReportSummaryUTest.java │ ├── assignment │ │ ├── AssignmentGroupUTest.java │ │ ├── AssignmentOverrideUTest.java │ │ └── AssignmentRetrieverUTest.java │ ├── authenticationLog │ │ └── AuthenticationLogUTest.java │ ├── calendar │ │ ├── CalendarReaderUTest.java │ │ └── CalendarWriterUTest.java │ ├── communicationChannel │ │ └── CommunicationChannelUTest.java │ ├── contentMigration │ │ └── ContentMigrationUTest.java │ ├── course │ │ ├── CourseGetUTest.java │ │ ├── CourseListingUTest.java │ │ ├── CourseManagerUTest.java │ │ ├── DropCourseUTest.java │ │ ├── SectionManagerUTest.java │ │ └── UserManagerUTest.java │ ├── file │ │ └── CourseGetUTest.java │ ├── gson │ │ └── GsonDateParsingUTest.java │ ├── login │ │ └── LoginUTest.java │ ├── module │ │ └── ModuleListingTest.java │ ├── quiz │ │ ├── QuizQuestionRetrieverUTest.java │ │ ├── QuizRetrieverUTest.java │ │ └── QuizSubmissionRetrieverUTest.java │ ├── roles │ │ └── RolesUTest.java │ ├── sisImport │ │ └── SisImportUTest.java │ ├── tab │ │ └── TabUTest.java │ └── user │ │ └── UserRetrieverUTest.java │ └── util │ └── JsonTestUtil.java └── resources ├── InvalidJson.json ├── SampleJson ├── BlankResponse.json ├── CreateUserResponse.json ├── EnrollmentDeleteResponse.json ├── EnrollmentResponse.json ├── EnrollmentTerm.json ├── Enrollments.json ├── Modules.json ├── Progress.json ├── account │ ├── AccountWithLtiGuid.json │ ├── FiveSubAccounts.json │ └── RootAccount.json ├── accountReport │ ├── AccountReportListing.json │ └── SingleAccountReportListing.json ├── accountReportSummary │ └── AccountReportSummary.json ├── assignment │ ├── Assignment2.json │ ├── AssignmentGroup.json │ ├── AssignmentGroupList.json │ ├── AssignmentGroupWithAssignments.json │ ├── AssignmentList.json │ ├── AssignmentOverride.json │ ├── AssignmentOverrideList.json │ └── MinimalAssignment.json ├── authenticationLog │ ├── AuthenticationLogForAccount.json │ ├── AuthenticationLogForLogin.json │ └── AuthenticationLogForUser.json ├── calendar │ ├── CalendarEvent.json │ ├── CalendarEvents.json │ ├── CalendarNotFound.json │ ├── CreateCalendarEvent.json │ ├── DeleteCalendarEvent.json │ └── EditCalendarEvent.json ├── communicationChannel │ ├── CommunicationChannelsList.json │ ├── CreateCommunicationChannelResponse.json │ ├── CreateCommunicationChannelSkipConfirmationResponse.json │ └── DeleteCommunicationChannelResponse.json ├── contentMigration │ ├── CreateContentMigrationRunning.json │ ├── CreateContentMigrationWaiting.json │ ├── CreateContentMigrationWithFile.json │ ├── CreateContentMigrationWithFile2.json │ ├── GetContentMigrationCompleted.json │ ├── GetContentMigrationCompletedWithIssues.json │ ├── GetContentMigrationSelectiveCompleted.json │ ├── GetMigrationIssue.json │ ├── GetSelectiveData.json │ └── GetSelectiveDataTypeAssignments.json ├── course │ ├── CreateCourseDateError.json │ ├── CreateCourseSuccess.json │ ├── DeleteConcludeCourseSuccess.json │ ├── DeleteCourseSuccess.json │ ├── GetCourseIncludeCourseImage.json │ ├── UpdateCourseSuccess.json │ └── UserCourseListResponse.json ├── file │ └── GetFileSuccess.json ├── login │ ├── DeleteLogin.json │ ├── GetLoginForUser.json │ ├── LoginUpdateFailedUniqueId.json │ └── UpdateLogin.json ├── oauth │ ├── InvalidAccessTokenResponse.json │ ├── InvalidClientIdResponse.json │ ├── InvalidRefreshTokenResponse.json │ ├── SuccessfulAccessTokenResponse.json │ └── UserUnauthorizedResponse.json ├── quiz │ ├── Quiz1.json │ ├── Quiz2.json │ ├── QuizList.json │ ├── QuizQuestionList.json │ ├── QuizSubmissions.json │ └── QuizSubmissionsIncludeUser.json ├── role │ └── Role.json ├── sampleErrorMessageWithErrorArray.json ├── sampleErrorMessageWithoutErrorArray.json ├── section │ ├── CreateSectionsSuccess.json │ └── Sections.json ├── sisImport │ └── SisImportCompleted.json ├── submission │ └── submissionResponse.json ├── tab │ └── UpdateTabSuccess.json └── user │ ├── IndividualUserList.json │ ├── LargeUserList.json │ ├── User1.json │ ├── User2.json │ ├── UserById.json │ ├── UserByIdLong.json │ ├── UserBySelfIdentifier.json │ ├── UserBySisIntegrationId.json │ ├── UserBySisUserId.json │ ├── UserCreateFailedDuplicateId.json │ ├── UserCreateFailedIntegrationId.json │ ├── UserCreateFailedSisId.json │ └── UserList.json ├── TestModels ├── TestModel.json ├── TestModels1.json └── TestModels2.json └── log4j.properties /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Cache local Maven repository 20 | uses: actions/cache@v2 21 | with: 22 | path: ~/.m2/repository 23 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 24 | restore-keys: | 25 | ${{ runner.os }}-maven- 26 | - name: Set up JDK 1.8 27 | uses: actions/setup-java@v1 28 | with: 29 | java-version: 1.8 30 | - name: Build with Maven 31 | run: mvn -B package --file pom.xml 32 | # This is part of the release task so we don't want to allow failures. 33 | - name: Build JavaDoc with Maven 34 | run: mvn -B javadoc:javadoc --file pom.xml 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | .settings 3 | integration.properties 4 | rebel.xml 5 | rebel-remote.xml 6 | *.iml 7 | *.idea 8 | release.properties -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | canvas-api 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.common.project.facet.core.builder 10 | 11 | 12 | 13 | 14 | org.eclipse.jdt.core.javabuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.m2e.core.maven2Builder 20 | 21 | 22 | 23 | 24 | org.eclipse.wst.validation.validationbuilder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jem.workbench.JavaEMFNature 31 | org.eclipse.wst.common.modulecore.ModuleCoreNature 32 | org.eclipse.jdt.core.javanature 33 | org.eclipse.m2e.core.maven2Nature 34 | org.eclipse.wst.common.project.facet.core.nature 35 | 36 | 37 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | @Library('jenkins-shared-libs') _ 2 | def config = [ appName: 'canvas-api', 3 | podName: 'java-11-maven-3.5.2.yaml', 4 | containerName: 'jdk-11-maven', 5 | runUnitTests: true, 6 | runIntegrationTests: false, 7 | runSonar: true 8 | ] 9 | javaPipeline(config) 10 | -------------------------------------------------------------------------------- /integration-example.properties: -------------------------------------------------------------------------------- 1 | # Copy this file to integration.properties and set values to run integration tests. 2 | # The URL of the Canvas instance, best to use a best instance as when test fail they may leave traces in Canvas. 3 | url=https://instance.beta.instructure.com/ 4 | # Set on live. 5 | # Token for a valid user who can create sections and create calendars in the course. 6 | token=11537~nqSvdZ55SkdnlqGyAuk7JHspdjlX7tZrXmjrlDMNLDWj2syiIwp4kwbrwJRS0nXC 7 | # ID of the user who's token it is. 8 | user=73 9 | # ID of course to use for course related tests. 10 | course=26841 11 | # ID of destination course to use for content migration. 12 | destination_course=26842 -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/annotation/CanvasField.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target(ElementType.METHOD) 10 | public @interface CanvasField { 11 | 12 | String postKey(); 13 | 14 | /* Controls whether the key should be wrapped in the CanvasObject's postName. 15 | * For example if the class's CanvasObject annotation contains the postKey value of 'course', 16 | * and the CanvasField has a postKey value of 'id' then: 17 | * Setting array to true will result in the postMap key be 'course[id]' 18 | * Setting array to false will result in the postMap key to be 'id' 19 | */ 20 | boolean array() default true; 21 | 22 | /* 23 | Used to override the key on the main Canvas Object. Leave empty unless necessary 24 | */ 25 | String overrideObjectKey() default ""; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/annotation/CanvasObject.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.annotation; 2 | 3 | import java.lang.annotation.Retention; 4 | import java.lang.annotation.RetentionPolicy; 5 | 6 | @Retention(RetentionPolicy.RUNTIME) 7 | public @interface CanvasObject { 8 | String postKey(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/constants/CanvasConstants.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.constants; 2 | 3 | public class CanvasConstants { 4 | 5 | private CanvasConstants(){} 6 | 7 | public static final String ACCOUNT_ID="1"; 8 | public static final String MASQUERADE_SIS_USER="sis_user_id"; 9 | public static final String MASQUERADE_CANVAS_USER="canvas_user_id"; 10 | 11 | public static final String URLENCODING_TYPE = "UTF-8"; 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/enums/SectionIncludes.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.enums; 2 | 3 | public enum SectionIncludes { 4 | STUDENTS, 5 | AVATAR_URL, 6 | ENROLLMENTS, 7 | TOTAL_STUDENTS, 8 | PASSBACK_STATUS; 9 | 10 | @Override 11 | public String toString() { 12 | return name().toLowerCase(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/enums/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Shared enums 3 | *

4 | * The hope was to consolidate enums, especially in the API options classes into 5 | * one place. The problem is that even when two different API calls accept (for 6 | * example) an enrollment_type parameter, they may either accept 7 | * different values or require different string literals for the same logical 8 | * value. 9 | *

10 | * Example: the List your courses API call takes an 11 | * enrollment_type parameter which accepts the values: teacher, 12 | * student, ta, observer, designer. The Get users in course API 13 | * call also has an enrollment_type parameter and accepts all the 14 | * previously listed ones plus student_view. The List enrollments 15 | * API call also has the same parameter but it requires the strings 16 | * StudentEnrollment, TeacherEnrollment, TaEnrollment, DesignerEnrollment, and 17 | * ObserverEnrollment. 18 | *

19 | * So all the enums ended up getting sucked into the options classes where they 20 | * could reflect the actual values that Canvas allows and is expecting. 21 | */ 22 | package edu.ksu.canvas.enums; -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/errors/ErrorDetails.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.errors; 2 | 3 | /** 4 | * This allows you to retrieve more information about what was wrong with your request. 5 | */ 6 | public class ErrorDetails { 7 | 8 | private String type; 9 | private String attribute; 10 | private String message; 11 | 12 | public String getAttribute() { 13 | return attribute; 14 | } 15 | 16 | public void setAttribute(String attribute) { 17 | this.attribute = attribute; 18 | } 19 | 20 | public String getType() { 21 | return type; 22 | } 23 | 24 | public void setType(String type) { 25 | this.type = type; 26 | } 27 | 28 | public String getMessage() { 29 | return message; 30 | } 31 | 32 | public void setMessage(String message) { 33 | this.message = message; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/errors/ErrorHandler.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.errors; 2 | 3 | import org.apache.http.HttpRequest; 4 | import org.apache.http.HttpResponse; 5 | 6 | /** 7 | * This allows additional specific behaviour for handling errors. 8 | */ 9 | public interface ErrorHandler { 10 | 11 | boolean shouldHandle(HttpRequest httpRequest, HttpResponse httpResponse); 12 | 13 | void handle(HttpRequest httpRequest, HttpResponse httpResponse); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/errors/GenericErrorResponse.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.errors; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * The error object that is returned when the creation of certain objects fails because the data isn't good. 8 | * This allows you to retrieve more information about what was wrong with your request. 9 | */ 10 | public class GenericErrorResponse { 11 | 12 | private Map> errors; 13 | 14 | public Map> getErrors() { 15 | return errors; 16 | } 17 | 18 | public void setErrors(Map> errors) { 19 | this.errors = errors; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/errors/UserErrorHandler.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.errors; 2 | 3 | import com.google.gson.Gson; 4 | import edu.ksu.canvas.exception.CanvasException; 5 | import edu.ksu.canvas.impl.GsonResponseParser; 6 | import org.apache.http.HttpRequest; 7 | import org.apache.http.HttpResponse; 8 | import org.apache.http.util.EntityUtils; 9 | 10 | import java.io.IOException; 11 | import java.util.regex.Pattern; 12 | 13 | /** 14 | * The error handler that should be used when creation of a user fails. 15 | */ 16 | public class UserErrorHandler implements ErrorHandler { 17 | 18 | private Pattern pattern = Pattern.compile("/api/v1/accounts/\\d+/users"); 19 | 20 | @Override 21 | public boolean shouldHandle(HttpRequest httpRequest, HttpResponse httpResponse) { 22 | return 23 | pattern.matcher(httpRequest.getRequestLine().getUri()).find() && 24 | httpResponse.getStatusLine().getStatusCode() == 400 && 25 | httpResponse.getEntity().getContentType().getValue().contains("application/json"); 26 | } 27 | 28 | @Override 29 | public void handle(HttpRequest httpRequest, HttpResponse httpResponse) { 30 | Gson gson = GsonResponseParser.getDefaultGsonParser(false); 31 | try { 32 | UserErrorResponse response = gson.fromJson(EntityUtils.toString(httpResponse.getEntity()), UserErrorResponse.class); 33 | if (response.getErrors() != null) { 34 | throw new CanvasException("Failed to create user.", httpRequest.getRequestLine().getUri(), response); 35 | } 36 | } catch (IOException e) { 37 | // Ignore. 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/errors/UserErrorResponse.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.errors; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | /** 7 | * The error object that is returned when the creation of a user fails because the data isn't good. 8 | * This allows you to retrieve more information about what was wrong with your request. 9 | */ 10 | public class UserErrorResponse { 11 | 12 | private Errors errors; 13 | 14 | public Errors getErrors() { 15 | return errors; 16 | } 17 | 18 | public void setErrors(Errors errors) { 19 | this.errors = errors; 20 | } 21 | 22 | public static class Errors { 23 | private Map> user; 24 | private Map> pseudonym; 25 | 26 | public Map> getUser() { 27 | return user; 28 | } 29 | 30 | public void setUser(Map> user) { 31 | this.user = user; 32 | } 33 | 34 | public Map> getPseudonym() { 35 | return pseudonym; 36 | } 37 | 38 | public void setPseudonym(Map> pseudonym) { 39 | this.pseudonym = pseudonym; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/CanvasException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Base exception for errors arising while talking to Canvas. 5 | * When thrown, it can optionally carry a string containing the 6 | * human readable error message returned by Canvas, if any. 7 | * Sometimes it may be appropriate to display this error message 8 | * to the user.It can also carry the URL of the failed request. 9 | */ 10 | public class CanvasException extends RuntimeException { 11 | private static final long serialVersionUID = 1L; 12 | 13 | private final String canvasErrorMessage; 14 | private final String requestUrl; 15 | private final Object error; 16 | 17 | public CanvasException() { 18 | canvasErrorMessage = null; 19 | requestUrl = null; 20 | error = null; 21 | } 22 | 23 | public CanvasException(String canvasErrorString, String url) { 24 | super(String.format("Error from URL %s : %s", url, canvasErrorString)); 25 | canvasErrorMessage = canvasErrorString; 26 | requestUrl = url; 27 | error = null; 28 | } 29 | 30 | public CanvasException(String canvasErrorString, String url, Object error) { 31 | canvasErrorMessage = canvasErrorString; 32 | requestUrl = url; 33 | this.error = error; 34 | } 35 | 36 | public Object getError() { 37 | return error; 38 | } 39 | 40 | public String getCanvasErrorMessage() { 41 | return canvasErrorMessage; 42 | } 43 | 44 | public String getRequestUrl() { 45 | return requestUrl; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/InvalidOauthTokenException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a 401 response with a WWW-Authenticate header present. 5 | * Sometimes this is just because the access token has expired and 6 | * needs to be refreshed. If this is the case, the exception will 7 | * be caught in the RefreshingRestClient class and handled. If this 8 | * exception makes it back up to the calling code, it probably means 9 | * that the user's refresh token (or the manually generated admin token) 10 | * is invalid. 11 | */ 12 | public class InvalidOauthTokenException extends CanvasException { 13 | private static final long serialVersionUID = 1L; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/ObjectNotFoundException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a 404 response. 5 | */ 6 | public class ObjectNotFoundException extends CanvasException { 7 | private static final long serialVersionUID = 1L; 8 | 9 | public ObjectNotFoundException() { 10 | super(); 11 | } 12 | 13 | public ObjectNotFoundException(String canvasErrorString, String url) { 14 | super(canvasErrorString, url); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/RateLimitException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a 403 Rate Limit Exceeded response. 5 | */ 6 | public class RateLimitException extends CanvasException { 7 | 8 | public RateLimitException() { 9 | super(); 10 | } 11 | 12 | public RateLimitException(String canvasErrorString, String url) { 13 | super(canvasErrorString, url); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/RetriableException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a retriable response, for example, a 504, Gateway Timeout. 5 | * This usually means that the front end web server has timed out while waiting for the 6 | * application server to complete the request. The request could still be in flight on 7 | * the application server but there is no guarantee as to what state it is in. 8 | * Usually you will probably want to retry the request. 9 | */ 10 | public class RetriableException extends CanvasException { 11 | private static final long serialVersionUID = 1L; 12 | 13 | public RetriableException() { 14 | super(); 15 | } 16 | 17 | public RetriableException(String canvasErrorString, String url) { 18 | super(canvasErrorString, url); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/ThrottlingException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a 403 response in response to too many API requests 5 | * See https://canvas.instructure.com/doc/api/file.throttling.html 6 | */ 7 | public class ThrottlingException extends CanvasException { 8 | private static final long serialVersionUID = 1L; 9 | 10 | public ThrottlingException() { 11 | super(); 12 | } 13 | 14 | public ThrottlingException(String canvasErrorString, String url) { 15 | super(canvasErrorString, url); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/UnauthorizedException.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.exception; 2 | 3 | /** 4 | * Thrown if Canvas returns a 401 response without a WWW-Authenticate header. 5 | * Indicates that the user does not have permission to access the 6 | * requested resource. I believe this is actually an incorrect use 7 | * of 401 and it should be 403 instead but this is how the Canvas API do. 8 | */ 9 | public class UnauthorizedException extends CanvasException { 10 | private static final long serialVersionUID = 1L; 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/exception/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Exceptions thrown when canvas returns errors. 3 | */ 4 | package edu.ksu.canvas.exception; -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/impl/AdminImpl.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.impl; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | 5 | import edu.ksu.canvas.interfaces.*; 6 | import edu.ksu.canvas.model.AccountAdmin; 7 | import edu.ksu.canvas.net.RestClient; 8 | import edu.ksu.canvas.oauth.OauthToken; 9 | import edu.ksu.canvas.requestOptions.ListAccountAdminsOptions; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.io.IOException; 15 | import java.lang.reflect.Type; 16 | import java.util.List; 17 | 18 | public class AdminImpl extends BaseImpl implements AdminReader, AdminWriter { 19 | private static final Logger LOG = LoggerFactory.getLogger(AdminImpl.class); 20 | 21 | public AdminImpl(String canvasBaseUrl, Integer apiVersion, OauthToken oauthToken, RestClient restClient, 22 | int connectTimeout, int readTimeout, Integer paginationPageSize, Boolean serializeNulls) { 23 | super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, 24 | paginationPageSize, serializeNulls); 25 | } 26 | 27 | @Override 28 | public List listAccountAdmins(ListAccountAdminsOptions options) throws IOException { 29 | LOG.debug("Getting list of account admins"); 30 | String url = buildCanvasUrl("accounts/" + options.getAccountId() + "/admins", options.getOptionsMap()); 31 | return getListFromCanvas(url); 32 | } 33 | 34 | @Override 35 | protected Type listType() { 36 | return new TypeToken>(){}.getType(); 37 | } 38 | 39 | @Override 40 | protected Class objectType() { 41 | return AccountAdmin.class; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/impl/ModuleImpl.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.impl; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import edu.ksu.canvas.interfaces.CanvasWriter; 5 | import edu.ksu.canvas.interfaces.ModuleReader; 6 | import edu.ksu.canvas.model.Module; 7 | import edu.ksu.canvas.net.RestClient; 8 | import edu.ksu.canvas.oauth.OauthToken; 9 | import edu.ksu.canvas.requestOptions.ListModulesOptions; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.io.IOException; 14 | import java.lang.reflect.Type; 15 | import java.util.List; 16 | 17 | public class ModuleImpl extends BaseImpl implements ModuleReader { 18 | private static final Logger LOG = LoggerFactory.getLogger(ModuleImpl.class); 19 | 20 | public ModuleImpl(final String canvasBaseUrl, final Integer apiVersion, final OauthToken oauthToken, final RestClient restClient, final int connectTimeout, final int readTimeout, final Integer paginationPageSize, final Boolean serializeNulls) { 21 | super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, paginationPageSize, serializeNulls); 22 | } 23 | 24 | @Override 25 | public List getModulesInCourse(final ListModulesOptions options) throws IOException { 26 | LOG.debug("Retrieving modules for course {}", options.getCourseId()); 27 | String url = buildCanvasUrl(String.format("courses/%d/modules", options.getCourseId()), options.getOptionsMap()); 28 | return getListFromCanvas(url); 29 | } 30 | 31 | @Override 32 | protected Class objectType() { 33 | return Module.class; 34 | } 35 | 36 | @Override 37 | protected Type listType() { 38 | return new TypeToken>() { 39 | }.getType(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/impl/RoleImpl.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.impl; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | 5 | import edu.ksu.canvas.interfaces.*; 6 | import edu.ksu.canvas.model.Role; 7 | import edu.ksu.canvas.net.RestClient; 8 | import edu.ksu.canvas.oauth.OauthToken; 9 | import edu.ksu.canvas.requestOptions.ListRolesOptions; 10 | 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.io.IOException; 15 | import java.lang.reflect.Type; 16 | import java.util.List; 17 | 18 | public class RoleImpl extends BaseImpl implements RoleReader, RoleWriter { 19 | private static final Logger LOG = LoggerFactory.getLogger(RoleImpl.class); 20 | 21 | public RoleImpl(String canvasBaseUrl, Integer apiVersion, OauthToken oauthToken, RestClient restClient, 22 | int connectTimeout, int readTimeout, Integer paginationPageSize, Boolean serializeNulls) { 23 | super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, 24 | paginationPageSize, serializeNulls); 25 | } 26 | 27 | @Override 28 | public List listRoles(ListRolesOptions options) throws IOException { 29 | LOG.debug("Retrieving roles for account {}", options.getAccountId()); 30 | String url = buildCanvasUrl("accounts/" + options.getAccountId() + "/roles", options.getOptionsMap()); 31 | return getListFromCanvas(url); 32 | } 33 | 34 | @Override 35 | protected Type listType() { 36 | return new TypeToken>(){}.getType(); 37 | } 38 | 39 | @Override 40 | protected Class objectType() { 41 | return Role.class; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/impl/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Default implementations for Canvas API calls. 3 | */ 4 | package edu.ksu.canvas.impl; 5 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AccountReportReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import java.util.Optional; 6 | 7 | import edu.ksu.canvas.model.report.AccountReport; 8 | 9 | public interface AccountReportReader extends CanvasReader { 10 | 11 | /** 12 | * Generate a list of previously run reports for a given report type. 13 | * @param accountId the account ID to run the reports against 14 | * @param report the specific name of the report (e.g. sis_export_csv) 15 | * @return a list of run reports specified by the report ID 16 | * @throws IOException When there is an error communicating with Canvas 17 | */ 18 | List listReports(String accountId, String report) throws IOException; 19 | 20 | /** 21 | * Pull back the status of a given report. 22 | * @param accountId the account ID to run the reports against 23 | * @param report the specific name of the report (e.g. sis_export_csv) 24 | * @param id the ID of the running report 25 | * @return a report outlining the status of its run, or a summary of its completed run 26 | * @throws IOException When there is an error communicating with Canvas 27 | */ 28 | Optional reportStatus(String accountId, String report, Long id) throws IOException; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AccountReportSummaryReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.report.AccountReportSummary; 7 | 8 | public interface AccountReportSummaryReader extends CanvasReader { 9 | 10 | /** 11 | * Generate a list of reports available for the specified account. 12 | * See the Canvas API documentation for more details. 13 | * @param accountId the account ID to run the reports against 14 | * @return a summary list of reports, showing the most recent runs if any exist 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | List listAvailableReports(String accountId) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AccountReportSummaryWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.report.AccountReportSummary; 4 | 5 | public interface AccountReportSummaryWriter extends CanvasWriter { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AccountReportWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.report.AccountReport; 7 | import edu.ksu.canvas.requestOptions.AccountReportOptions; 8 | 9 | public interface AccountReportWriter extends CanvasWriter { 10 | 11 | /** 12 | * Start a new report, specifying a set of options to run with. 13 | *

14 | * Note that the options used vary depending on the report you wish to start. 15 | * @param options options that should be passed to start the report 16 | * @return an Optional<AccountReport> which contains a reference to the generated report 17 | * @throws IOException When there is an error communicating with Canvas 18 | * @see Account Report API documentation 19 | * @see AccountReportOptions 20 | */ 21 | Optional startReport(AccountReportOptions options) throws IOException; 22 | 23 | 24 | /** 25 | * Delete a report. This can also be used to stop the run of a report. 26 | * @param accountId the account id used to generate the report 27 | * @param report the name of the report 28 | * @param reportId the ID of the report 29 | * @return an Optional<AccountReport> which contains a reference to the deleted report 30 | * @throws IOException When there is an error communicating with Canvas 31 | * @see Account Report API documentation 32 | */ 33 | Optional deleteReport(String accountId, String report, Long reportId) throws IOException; 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AccountWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Account; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface AccountWriter extends CanvasWriter { 9 | /** 10 | * Create a new account in Canvas 11 | * @param accountId the account ID of the account under which to place this account 12 | * @param account A account object containing the information needed to create a account in Canvas 13 | * @return The newly created account 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | Optional createAccount(String accountId, Account account) throws IOException; 17 | 18 | /** 19 | * Update a account in Canvas 20 | * @param account A account object containing the information needed to update a account in Canvas 21 | * @return The newly updated account 22 | * @throws IOException When there is an error communicating with Canvas 23 | */ 24 | Optional updateAccount(Account account) throws IOException; 25 | 26 | /** 27 | * @param parentAccountId The ID of the parent account to the account to delete. 28 | * @param accountId The ID of the account you wish to delete 29 | * @return true if the account was deleted 30 | * @throws IOException When there is an error communicating with Canvas 31 | */ 32 | Boolean deleteAccount(String parentAccountId, String accountId) throws IOException; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AdminReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.AccountAdmin; 4 | import edu.ksu.canvas.requestOptions.ListAccountAdminsOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | public interface AdminReader extends CanvasReader { 10 | /** 11 | * Return a list of account admins that the current user can view or manage. 12 | * @param options Object encapsulating parameters to the list accounts API call 13 | * @return List of account admins 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | List listAccountAdmins(ListAccountAdminsOptions options) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AdminWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.AccountAdmin; 4 | 5 | public interface AdminWriter extends CanvasWriter { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AssignmentGroupReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.AssignmentGroup; 4 | import edu.ksu.canvas.requestOptions.GetAssignmentGroupOptions; 5 | import edu.ksu.canvas.requestOptions.ListAssignmentGroupOptions; 6 | 7 | import java.io.IOException; 8 | import java.util.List; 9 | import java.util.Optional; 10 | 11 | public interface AssignmentGroupReader extends CanvasReader{ 12 | 13 | /** 14 | * Return a list of AssignmentGroups that the current user can view or manage. 15 | * @param options A mapping of optional parameters for assignment groups 16 | * @return List of AssignmentGroups 17 | * @throws IOException When there is an error communicating with Canvas 18 | */ 19 | List listAssignmentGroup(ListAssignmentGroupOptions options) throws IOException; 20 | 21 | /** 22 | * Returns the requested assignment group by ID 23 | * @param options Collection of optional parameters to the Canvas API 24 | * @return The requested assignment group 25 | * @throws IOException When there is an error communicating with Canvas 26 | */ 27 | Optional getAssignmentGroup(GetAssignmentGroupOptions options) throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AssignmentOverrideReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.AssignmentOverride; 4 | import java.io.IOException; 5 | import java.util.List; 6 | import java.util.Optional; 7 | 8 | public interface AssignmentOverrideReader extends CanvasReader { 9 | 10 | /*** 11 | * Returns the list of overrides for this assignment that target sections/groups/students visible to the current user. 12 | * @param courseId Canvas course ID or "sis_course_id:1234" for SIS course ID 13 | * @param assignmentId Canvas assignment ID 14 | * @return List of assignment overrides 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | List listAssignmentOverrides(String courseId, Long assignmentId) throws IOException; 18 | 19 | /*** 20 | * Returns details of the the override with the given id. 21 | * @param courseId Canvas course ID or "sis_course_id:1234" for SIS course ID 22 | * @param assignmentId Canvas assignment ID 23 | * @param overrideId Canvas ID of the specific assignment override to query for 24 | * @return The requested assigment override object 25 | * @throws IOException When there is an error communicating with Canvas 26 | */ 27 | Optional getAssignmentOverride(String courseId, Long assignmentId, Long overrideId) throws IOException; 28 | } -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AssignmentOverrideWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.assignment.AssignmentOverride; 7 | 8 | public interface AssignmentOverrideWriter extends CanvasWriter { 9 | 10 | /** 11 | * Creates an assignment override in canvas. The override object must have an assignment ID set. 12 | * @param courseId Course that the assignment is in 13 | * @param assignmentOverride The Override object to create 14 | * @return AssignmentOverride object created in Canvas 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional createAssignmentOverride(String courseId, AssignmentOverride assignmentOverride) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AssignmentWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.assignment.Assignment; 7 | 8 | public interface AssignmentWriter extends CanvasWriter { 9 | 10 | /** 11 | * Create an assignment in Canvas. The only required field is name. 12 | * @param courseId ID of the course to create the assignment in 13 | * @param assignment Assignment object to create. Must have at least a name set 14 | * @return The created assignment object 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional createAssignment(String courseId, Assignment assignment) throws IOException; 18 | 19 | /** 20 | * Deletes a specified assignment in canvas 21 | * @param courseId Course ID of course to delete assignment from 22 | * @param assignmentId Assignment ID of assignment to delete 23 | * @return The deleted Assignment object as returned by the Canvas API 24 | * @throws IOException When there is an error communicating with Canvas 25 | */ 26 | Optional deleteAssignment(String courseId, Long assignmentId) throws IOException; 27 | 28 | /** 29 | * Writes an Assignment object to the Canvas API 30 | * @param courseId Course ID that this assignment is associated with 31 | * @param assignment The assignment settings to write to the API 32 | * @return The modified Assignment returned by the API 33 | * @throws IOException When there is an error communicating with Canvas 34 | */ 35 | Optional editAssignment(String courseId, Assignment assignment) throws IOException; 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/AuthenticationLogReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.AuthenticationLog; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface AuthenticationLogReader extends CanvasReader { 9 | 10 | /** 11 | * Returns an authentication log. 12 | * @param accountId The account ID for the authentication log 13 | * @return An authentication log 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | Optional getAuthenticationLogForAccount(String accountId) throws IOException; 17 | 18 | /** 19 | * Returns an authentication log. 20 | * @param loginId The login ID for the authentication log 21 | * @return An authentication log 22 | * @throws IOException When there is an error communicating with Canvas 23 | */ 24 | Optional getAuthenticationLogForLogin(String loginId) throws IOException; 25 | 26 | /** 27 | * Returns an authentication log. 28 | * @param userId The user ID for the authentication log 29 | * @return An authentication log 30 | * @throws IOException When there is an error communicating with Canvas 31 | */ 32 | Optional getAuthenticationLogForUser(String userId) throws IOException; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CalendarWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.CalendarEvent; 4 | import edu.ksu.canvas.requestOptions.DeleteCalendarEventOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.Optional; 8 | 9 | /** 10 | * Methods to manipulate calendar events in Canvas. 11 | * @see Canvas calendar event documentation 12 | * 13 | */ 14 | public interface CalendarWriter extends CanvasWriter { 15 | 16 | /** 17 | * Delete a calendar event from Canvas. 18 | * @param options Options class containing required and optional parameters for the delete action 19 | * @return The deleted calendar event 20 | * @throws IOException When there is an error communicating with Canvas 21 | */ 22 | Optional deleteCalendarEvent(DeleteCalendarEventOptions options) throws IOException; 23 | 24 | /** 25 | * Create a new calendar event in Canvas. 26 | * @param calendarEvent Calendar event object to persist to Canvas. Context code is required. 27 | * @return The newly created calendar event 28 | * @throws IOException When there is an error communicating with Canvas 29 | */ 30 | Optional createCalendarEvent(CalendarEvent calendarEvent) throws IOException; 31 | 32 | /** 33 | * Modify a calendar event in Canvas. 34 | * @param calendarEvent An existing calendar event to modify 35 | * @return The updated calendar event 36 | * @throws IOException When there is an error communicating with Canvas 37 | */ 38 | Optional editCalendarEvent(CalendarEvent calendarEvent) throws IOException; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CanvasReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | 7 | public interface CanvasReader { 8 | /* 9 | * Perform an operation with a callback. This is used to 10 | * to perform operations on paginated calls before the final 11 | * response is complete. 12 | */ 13 | READERTYPE withCallback(Consumer> responseConsumer); 14 | 15 | READERTYPE readAsCanvasUser(String masqueradeAs); 16 | 17 | READERTYPE readAsSisUser(String masqueradeAs); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CanvasWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | public interface CanvasWriter { 4 | 5 | WRITERTYPE writeAsCanvasUser(String masqueradeAs); 6 | 7 | WRITERTYPE writeAsSisUser(String masqueradeAs); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CommunicationChannelReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.CommunicationChannel; 4 | 5 | import java.io.IOException; 6 | import java.util.List; 7 | 8 | public interface CommunicationChannelReader extends CanvasReader { 9 | /** 10 | * Retrieve a user's communication channels. 11 | * @param userId the id of the user to retrieve communication channels for 12 | * @return List of the user's communication channels 13 | * @throws IOException When there is an error communicating with Canvas 14 | */ 15 | public List getCommunicationChannelsForUser(String userId) throws IOException; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CommunicationChannelWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.CommunicationChannel; 7 | import edu.ksu.canvas.requestOptions.CreateCommunicationChannelOptions; 8 | 9 | public interface CommunicationChannelWriter extends CanvasWriter { 10 | 11 | /** 12 | * Adds a communication channel to a Canvas user. 13 | * @param options The communication channel to create. Must contain user ID and address. 14 | * @return The created communication channel object if creation was successful 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional createCommunicationChannel(CreateCommunicationChannelOptions options) throws IOException; 18 | 19 | /** 20 | * Delete a communication channel from Canvas 21 | * @param cc The communication channel record to delete. Must contain User ID and communication channel ID. 22 | * @return The now deleted communication channel record 23 | * @throws IOException When there is an error communicating with Canvas 24 | */ 25 | Optional deleteCommunicationChannel(CommunicationChannel cc) throws IOException; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ContentMigrationWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.ContentMigration; 4 | import edu.ksu.canvas.requestOptions.CreateContentMigrationOptions; 5 | import edu.ksu.canvas.requestOptions.CreateCourseContentMigrationOptions; 6 | 7 | import java.io.IOException; 8 | 9 | import java.util.Optional; 10 | 11 | public interface ContentMigrationWriter extends CanvasWriter{ 12 | 13 | Optional createCourseContentMigration(CreateCourseContentMigrationOptions options) throws IOException; 14 | Optional updateCourseContentMigration(Long id, CreateCourseContentMigrationOptions options) throws IOException; 15 | 16 | Optional createUserContentMigration(CreateContentMigrationOptions options) throws IOException; 17 | Optional updateUserContentMigration(Long id, CreateContentMigrationOptions options) throws IOException; 18 | 19 | Optional createGroupContentMigration(CreateContentMigrationOptions options) throws IOException; 20 | Optional updateGroupContentMigration(Long id, CreateContentMigrationOptions options) throws IOException; 21 | 22 | Optional createAccountContentMigration(CreateContentMigrationOptions options) throws IOException; 23 | Optional updateAccountContentMigration(Long id, CreateContentMigrationOptions options) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ConversationReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.Conversation; 7 | import edu.ksu.canvas.requestOptions.GetSingleConversationOptions; 8 | 9 | public interface ConversationReader extends CanvasReader { 10 | 11 | /** 12 | * Get a single conversation from Canvas 13 | * @param options API options for the conversation call 14 | * @return The requested conversation, if it exists 15 | * @throws IOException if there is an error communicating with Canvas 16 | */ 17 | public Optional getSingleConversation(GetSingleConversationOptions options) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CourseSettingsReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.CourseSettings; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface CourseSettingsReader extends CanvasReader { 9 | 10 | /** 11 | * Returns course settings from Canvas 12 | *

13 | * See Get course settings 14 | * in the Canvas docs for details. 15 | * @param courseId The Canvas ID of the course or sis_course_id:SISID 16 | * @return The course settings from Canvas 17 | * @throws IOException When there is an error communicating with Canvas 18 | */ 19 | Optional getCourseSettings(String courseId) throws IOException; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/CourseSettingsWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.CourseSettings; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface CourseSettingsWriter extends CanvasWriter { 9 | 10 | /** 11 | * Push modified course settings to Canvas. 12 | *

13 | * Only fields with the @CanvasField annotation can be changed. 14 | * @param courseId Canvas ID (or sis_course_id:XXXX) of the course 15 | * @param settings New settings to push to Canvas 16 | * @return The updated course settings 17 | * @throws IOException When there is an error communicating with Canvas 18 | */ 19 | Optional updateCourseSettings(String courseId, CourseSettings settings) throws IOException; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/EnrollmentReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Enrollment; 4 | import edu.ksu.canvas.requestOptions.GetEnrollmentOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | public interface EnrollmentReader extends CanvasReader { 10 | /** 11 | * Retrieve a user's enrollments. Object ID in the options class must be a user ID. 12 | * @param options API options available to this call 13 | * @return List of the user's enrollments 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | List getUserEnrollments(GetEnrollmentOptions options) throws IOException; 17 | 18 | /** 19 | * Retrieve enrollments in a given section. Object ID in the options class must be a section ID. 20 | * @param options API options available to this call 21 | * @return List of enrollments in a section 22 | * @throws IOException When there is an error communicating with Canvas 23 | */ 24 | List getSectionEnrollments(GetEnrollmentOptions options) throws IOException; 25 | 26 | /** 27 | * Retrieve enrollments in a given course. Object ID in the options class must be a course ID. 28 | * @param options API options available to this call 29 | * @return List of enrollments in a course 30 | * @throws IOException When there is an error communicating with Canvas 31 | */ 32 | List getCourseEnrollments(GetEnrollmentOptions options) throws IOException; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/EnrollmentTermReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.EnrollmentTerm; 4 | import edu.ksu.canvas.requestOptions.GetEnrollmentTermOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public interface EnrollmentTermReader extends CanvasReader { 11 | 12 | /** 13 | * Retrieve the enrollment terms for a single account. 14 | * @param options API options available to this call 15 | * @return the list of enrollment terms for that account 16 | * @throws IOException When there is an error communicating with Canvas 17 | */ 18 | List getEnrollmentTerms(GetEnrollmentTermOptions options) throws IOException; 19 | 20 | /** 21 | * Get a single enrollment term. 22 | * @param accountId The account ID to look in. 23 | * @param termId The term ID to lookup. 24 | * @return an Optional EnrollmentTerm for the ID. 25 | * @throws IOException When there is an error communicating with Canvas 26 | */ 27 | Optional getEnrollmentTerm(String accountId, String termId) throws IOException; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/EnrollmentTermWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | 4 | import edu.ksu.canvas.model.EnrollmentTerm; 5 | 6 | public interface EnrollmentTermWriter extends CanvasWriter { 7 | 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FeatureFlagReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.FeatureFlag; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface FeatureFlagReader extends CanvasReader { 9 | 10 | Optional getCourseFeatureFlag(String courseId, String feature) throws IOException; 11 | Optional getAccountFeatureFlag(String accountId, String feature) throws IOException; 12 | Optional getUserFeatureFlag(String userId, String feature) throws IOException; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FeatureFlagWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.FeatureFlag; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface FeatureFlagWriter extends CanvasWriter { 9 | 10 | Optional updateCourseFeatureFlag(String courseId, String feature, FeatureFlag.State state) throws IOException; 11 | Optional updateAccountFeatureFlag(String accountId, String feature, FeatureFlag.State state) throws IOException; 12 | Optional updateUserFeatureFlag(String userId, String feature, FeatureFlag.State state) throws IOException; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FeatureReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Feature; 4 | 5 | import java.io.IOException; 6 | import java.util.List; 7 | 8 | public interface FeatureReader extends CanvasReader { 9 | 10 | List getCourseFeatures(String courseId) throws IOException; 11 | 12 | List getAccountFeatures(String accountId) throws IOException; 13 | 14 | List getUserFeatures(String userId) throws IOException; 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FeatureWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Feature; 4 | 5 | public interface FeatureWriter extends CanvasWriter { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FileReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.File; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | /** 9 | * This is just used for getting a file after it's been uploaded at the moment. 10 | */ 11 | public interface FileReader extends CanvasReader { 12 | 13 | /** 14 | * This is used primarily when you have a redirect after you've uploaded a file. 15 | * @param url The URL of the file that has been uploaded. 16 | * @return The file object wrapped in an optional. 17 | * @throws IOException When there is an error communicating with Canvas 18 | */ 19 | Optional getFile(String url) throws IOException; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/FileWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Deposit; 4 | import edu.ksu.canvas.model.File; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.Optional; 9 | 10 | /** 11 | * This just allows you to upload a file once you've requested a file to be uploaded. 12 | * https://canvas.instructure.com/doc/api/file.file_uploads.html 13 | */ 14 | public interface FileWriter extends CanvasWriter { 15 | 16 | Optional upload(Deposit deposit, InputStream in, String filename) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/GradingStandardWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.GradingStandard; 4 | 5 | public interface GradingStandardWriter extends CanvasWriter { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/LoginReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Login; 4 | 5 | import java.io.IOException; 6 | import java.util.List; 7 | 8 | public interface LoginReader extends CanvasReader { 9 | /** 10 | * Retrieve a user's logins. 11 | * @param userId the id of the user to retrieve logins for 12 | * @return List of the user's logins 13 | * @throws IOException When there is an error communicating with Canvas 14 | */ 15 | public List getLoginForUser(String userId) throws IOException; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/LoginWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.Login; 7 | 8 | public interface LoginWriter extends CanvasWriter { 9 | 10 | /** 11 | * Write changes to a login to Canvas. 12 | * @param login The modified login to update. Must contain account ID and login ID. 13 | * @return The modified login object if update was successful 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | Optional updateLogin(Login login) throws IOException; 17 | 18 | /** 19 | * Delete a login from Canvas 20 | * @param login The login record to delete. Must contain User ID and login ID. 21 | * @return The now deleted login record 22 | * @throws IOException When there is an error communicating with Canvas 23 | */ 24 | Optional deleteLogin(Login login) throws IOException; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ModuleReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Module; 4 | import edu.ksu.canvas.requestOptions.ListModulesOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | public interface ModuleReader extends CanvasReader { 10 | /** 11 | * Retrieve the list of modules in a course. 12 | * 13 | * @param options The object holding options for this API call 14 | * @return List of the course's modules 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | public List getModulesInCourse(ListModulesOptions options) throws IOException; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/PageWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.Page; 7 | 8 | public interface PageWriter extends CanvasWriter { 9 | 10 | /** 11 | * Save a course page to Canvas 12 | * @param page The page object to save 13 | * @param courseId The Canvas course ID that this page is to be saved to 14 | * @return The update page after saving 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional updateCoursePage(Page page, String courseId) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ProgressReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Progress; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface ProgressReader extends CanvasReader { 9 | /** 10 | * Returns the progress of an asynchronous process by progress URL 11 | * @param url The URL to query for progress 12 | * @return A Progress object 13 | * @throws IOException When there is an error communicating with Canvas 14 | */ 15 | Optional getProgress(String url) throws IOException; 16 | 17 | /** 18 | * Returns the progress of an asynchronous process by progress ID 19 | * @param progressId ID of the progress object to query 20 | * @return The requested Progress object 21 | * @throws IOException When there is an error communicating with Canvas 22 | */ 23 | Optional getProgress(Long progressId) throws IOException; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ProgressWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Progress; 4 | 5 | public interface ProgressWriter extends CanvasWriter { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizQuestionReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.assignment.QuizQuestion; 7 | import edu.ksu.canvas.requestOptions.GetQuizQuestionsOptions; 8 | 9 | public interface QuizQuestionReader extends CanvasReader { 10 | /** 11 | * Retrieve a list of quiz questions from Canvas by its course and quiz Canvas ID numbers 12 | * @param options The API options associated with this request 13 | * @return List of quizzes questions in the course with the course ID 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | List getQuizQuestions(GetQuizQuestionsOptions options) throws IOException; 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizQuestionWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | 5 | import edu.ksu.canvas.model.assignment.QuizQuestion; 6 | 7 | public interface QuizQuestionWriter extends CanvasWriter { 8 | 9 | /** 10 | * Delete a quiz question 11 | * @param courseId Course ID containing the quiz to modify 12 | * @param quizId Quiz ID with question to delete 13 | * @param questionId Question ID of question to delete 14 | * @return true if deletion was successful (API returned HTTP 204), false otherwise 15 | * @throws IOException if there is an error communicating with Canvas 16 | */ 17 | public boolean deleteQuizQuestion(String courseId, Long quizId, Long questionId) throws IOException; 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | import java.util.Optional; 6 | 7 | import edu.ksu.canvas.model.assignment.Quiz; 8 | 9 | public interface QuizReader extends CanvasReader{ 10 | /** 11 | * Retrieve a specific quiz from Canvas by its course and quiz Canvas ID numbers 12 | * @param courseId The Canvas ID of the course 13 | * @param quizId The Canvas ID of the quiz 14 | * @return The assignment returned by Canvas or an empty Optional 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional getSingleQuiz(String courseId, String quizId) throws IOException; 18 | 19 | /** 20 | * Retrieve a list of quizzes from Canvas by its course Canvas ID number 21 | * @param courseId The Canvas ID of the course 22 | * @return List of quizzes in the course with the course ID 23 | * @throws IOException When there is an error communicating with Canvas 24 | */ 25 | List getQuizzesInCourse(String courseId) throws IOException; 26 | } -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizSubmissionQuestionReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.QuizSubmissionQuestion; 4 | 5 | public interface QuizSubmissionQuestionReader extends CanvasReader { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizSubmissionQuestionWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import javax.validation.constraints.NotNull; 7 | 8 | import edu.ksu.canvas.model.assignment.QuizSubmissionQuestion; 9 | import edu.ksu.canvas.requestOptions.AnswerQuizQuestionOptions; 10 | 11 | public interface QuizSubmissionQuestionWriter extends CanvasWriter { 12 | /** 13 | * Answers questions on behalf of a user. 14 | * @param options API options object for this call 15 | * @param answerArrayJson JsonArray of question objects. Answers may be in several formats: https://canvas.instructure.com/doc/api/quiz_submission_questions.html#Question+Answer+Formats-appendix 16 | * @return List of Quiz Submission Questions that Canvas returns from the request 17 | * @throws IOException When there is an error communicating with Canvas 18 | */ 19 | List answerQuestions(@NotNull AnswerQuizQuestionOptions options, @NotNull String answerArrayJson) 20 | throws IOException; 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizSubmissionReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.assignment.QuizSubmission; 7 | import edu.ksu.canvas.model.assignment.QuizSubmissionResponse; 8 | import edu.ksu.canvas.requestOptions.GetQuizSubmissionsOptions; 9 | 10 | public interface QuizSubmissionReader extends CanvasReader { 11 | /** 12 | * Retrieve a list of quiz submissions from Canvas by its course and quiz Canvas ID numbers 13 | * @param courseId The Canvas ID of the course 14 | * @param quizId The Canvas ID of the quiz 15 | * @return List of quiz submissions in the course with the course ID 16 | * @throws IOException When there is an error communicating with Canvas 17 | */ 18 | List getQuizSubmissions(String courseId, String quizId) throws IOException; 19 | 20 | /** 21 | * Retrieve a list of quiz submissions with user and quiz information optionally included 22 | * 23 | * @param options Options class containing required and optional parameters for this API call 24 | * @return List of quiz submissions in the course with the course ID 25 | * @throws IOException When there is an error communicating with Canvas 26 | */ 27 | QuizSubmissionResponse getQuizSubmissions(GetQuizSubmissionsOptions options) throws IOException; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizSubmissionWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.QuizSubmission; 4 | import edu.ksu.canvas.requestOptions.CompleteQuizSubmissionOptions; 5 | import edu.ksu.canvas.requestOptions.StartQuizSubmissionOptions; 6 | 7 | import java.io.IOException; 8 | import java.util.Optional; 9 | 10 | public interface QuizSubmissionWriter extends CanvasWriter { 11 | 12 | /** 13 | * Opens a quiz submission which can be used to answer questions and submit answers 14 | * @param options API options to be used to open a submission 15 | * @return The quiz submission object created by Canvas 16 | * @throws IOException If there is an error talking to Canvas 17 | */ 18 | Optional startQuizSubmission(StartQuizSubmissionOptions options)throws IOException; 19 | 20 | /** 21 | * Finish a quiz submission. This turns it in and grades it. After this call, no further modifications are allowed. 22 | * @param options API options to be used in closing the submission 23 | * @return The quiz submission object returned by Canvas 24 | * @throws IOException If there is an error talking to Canvas 25 | */ 26 | Optional completeQuizSubmission(CompleteQuizSubmissionOptions options) throws IOException; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/QuizWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.assignment.Quiz; 7 | 8 | public interface QuizWriter extends CanvasWriter { 9 | /** 10 | * 11 | * @param quiz The quiz to update 12 | * @param courseId The course ID in which the quiz lives 13 | * @return The updated Quiz object 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | Optional updateQuiz(Quiz quiz, String courseId) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/ResponseParser.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.lang.reflect.Type; 4 | import java.util.List; 5 | import java.util.Map; 6 | import java.util.Optional; 7 | 8 | import edu.ksu.canvas.net.Response; 9 | 10 | public interface ResponseParser { 11 | List parseToList(Type type, Response response); 12 | Optional parseToObject(Class clazz, Response response); 13 | Map parseToMap(Class clazz, Response response); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/RoleReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Role; 4 | import edu.ksu.canvas.requestOptions.ListRolesOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | 9 | public interface RoleReader extends CanvasReader { 10 | /** 11 | * Return a list of roles for an account. 12 | * @param options Object encapsulating parameters to the list accounts API call 13 | * @return List of roles 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | public List listRoles(ListRolesOptions options) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/RoleWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.Role; 4 | 5 | public interface RoleWriter extends CanvasWriter { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/RubricReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.Rubric; 4 | import edu.ksu.canvas.requestOptions.GetRubricOptions; 5 | 6 | import java.io.IOException; 7 | import java.util.Optional; 8 | 9 | public interface RubricReader extends CanvasReader { 10 | 11 | /** 12 | * Get a single rubric by ID from an account. 13 | * @param options Request parameters 14 | * @return The requested rubric object associated with an account 15 | * @throws IOException When there is an error communicating with Canvas 16 | */ 17 | Optional getRubricInAccount(GetRubricOptions options) throws IOException; 18 | 19 | /** 20 | * Get a single rubric by ID from a course. 21 | * @param options Request parameters 22 | * @return The requested rubric object associated with a course 23 | * @throws IOException When there is an error communicating with Canvas 24 | */ 25 | Optional getRubricInCourse(GetRubricOptions options) throws IOException; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/RubricWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.assignment.Rubric; 4 | 5 | public interface RubricWriter extends CanvasWriter { 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/SectionReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.enums.SectionIncludes; 4 | import edu.ksu.canvas.model.Section; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | import java.util.Optional; 9 | /** 10 | * Methods to read information from and about sections 11 | */ 12 | public interface SectionReader extends CanvasReader { 13 | 14 | /** 15 | * Return a list of sections in a given course 16 | * @param courseId Canvas ID of course 17 | * @param includes Optional information to include in the returned sections 18 | * @return List of sections 19 | * @throws IOException When there is an error communicating with Canvas 20 | */ 21 | List

listCourseSections(String courseId, List includes) throws IOException; 22 | 23 | /** 24 | * Return a single section with a given section ID 25 | * @param sectionId Section ID of section 26 | * @return The section 27 | * @throws IOException When there is an error communicating with Canvas 28 | */ 29 | Optional
getSingleSection(String sectionId) throws IOException; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/SisImportReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.SisImport; 4 | 5 | import java.io.IOException; 6 | import java.util.Optional; 7 | 8 | public interface SisImportReader extends CanvasReader { 9 | /** 10 | * Returns a sis import. 11 | * @param accountId The account ID for this API call 12 | * @param id The Canvas ID of the sis import to query 13 | * @return A SisImport object 14 | * @throws IOException When there is an error communicating with Canvas 15 | */ 16 | Optional getSisImport(String accountId, Long id) throws IOException; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/SisImportWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.model.SisImport; 4 | import edu.ksu.canvas.requestOptions.CreateSisImportOptions; 5 | 6 | import java.io.IOException; 7 | 8 | import java.util.Optional; 9 | 10 | public interface SisImportWriter extends CanvasWriter{ 11 | 12 | Optional createSisImport(CreateSisImportOptions options) throws IOException; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/SubmissionWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | 4 | import edu.ksu.canvas.model.Progress; 5 | import edu.ksu.canvas.model.assignment.Submission; 6 | import edu.ksu.canvas.requestOptions.MultipleSubmissionsOptions; 7 | 8 | import java.io.IOException; 9 | import java.util.Optional; 10 | 11 | public interface SubmissionWriter extends CanvasWriter { 12 | 13 | /** 14 | * Update the grading and comments on multiple student's assignment submissions in an asynchronous job. By section. 15 | * 16 | * @param options Parameters object containing parameters such as: section_id, assignment_id, student_id, 17 | * posted_grade, text_comment, group_comment, excuse, media_comment_id, media_comment_type. 18 | * @return The progress object created by Canvas 19 | * @throws IOException If there is an error talking to Canvas 20 | */ 21 | Optional gradeMultipleSubmissionsBySection(MultipleSubmissionsOptions options)throws IOException; 22 | 23 | /** 24 | * Update the grading and comments on multiple student's assignment submissions in an asynchronous job. By Course. 25 | * 26 | * @param options Parameters object containing parameters such as: course_id, assignment_id, student_id, 27 | * posted_grade, text_comment, group_comment, excuse, media_comment_id, media_comment_type. 28 | * @return The progress object created by Canvas 29 | * @throws IOException If there is an error talking to Canvas 30 | */ 31 | public Optional gradeMultipleSubmissionsByCourse(MultipleSubmissionsOptions options) throws IOException; 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/TabReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.Tab; 7 | 8 | /** 9 | * Methods to read information about tabs, which can be applied to courses 10 | * or groups. 11 | *

12 | * See https://canvas.colorado.edu/doc/api/tabs.html for the Canvas API 13 | * documentation. 14 | */ 15 | public interface TabReader extends CanvasReader { 16 | 17 | /** 18 | * Lists the navigation tabs for the given course. 19 | * 20 | * @param courseId identifies the course 21 | * @param includeExternalTools includes external tool tabs in the results 22 | * @return list of available tabs 23 | * @throws IOException When there is an error communicating with Canvas 24 | */ 25 | List listAvailableCourseTabs(String courseId, boolean includeExternalTools) throws IOException; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/TabWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.model.Tab; 7 | import edu.ksu.canvas.requestOptions.UpdateCourseTabOptions; 8 | 9 | /** 10 | * Methods to modify tabs, which can be applied to courses or groups. 11 | *

12 | * See https://canvas.colorado.edu/doc/api/tabs.html for the Canvas API 13 | * documentation. 14 | */ 15 | public interface TabWriter extends CanvasWriter { 16 | 17 | /** 18 | * Modifies a tab. 19 | * 20 | * @param options options specifying the course, tab, and what to modify 21 | * @return modified tab object 22 | * @throws IOException When there is an error communicating with Canvas 23 | */ 24 | Optional updateCourseTab(UpdateCourseTabOptions options) throws IOException; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/UserWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.interfaces; 2 | 3 | import edu.ksu.canvas.exception.InvalidOauthTokenException; 4 | import edu.ksu.canvas.model.User; 5 | import edu.ksu.canvas.requestOptions.CreateUserOptions; 6 | 7 | import java.io.IOException; 8 | import java.util.Optional; 9 | 10 | public interface UserWriter extends CanvasWriter { 11 | /** 12 | * Create a new user in Canvas 13 | * @param user user data for creating user account 14 | * @return The newly created user 15 | * @throws InvalidOauthTokenException When the supplied OAuth token is not valid 16 | * @throws IOException When there is an error communicating with Canvas 17 | */ 18 | Optional createUser(User user) throws InvalidOauthTokenException, IOException; 19 | 20 | /** 21 | * Create a new user in Canvas 22 | * @param user user data for creating user account 23 | * @param options the options for the user creation 24 | * @return The newly created user 25 | * @throws InvalidOauthTokenException When the supplied OAuth token is not valid 26 | * @throws IOException When there is an error communicating with Canvas 27 | */ 28 | Optional createUser (User user, CreateUserOptions options) throws InvalidOauthTokenException, IOException; 29 | 30 | 31 | /** 32 | * Update user information 33 | * @param user The user object with updated data to push to Canvas 34 | * @return The updated user 35 | * @throws InvalidOauthTokenException When the supplied OAuth token is not valid 36 | * @throws IOException When there is an error communicating with Canvas 37 | */ 38 | Optional updateUser(User user) throws InvalidOauthTokenException, IOException; 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/interfaces/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Interfaces defining Canvas API functionality 3 | */ 4 | package edu.ksu.canvas.interfaces; 5 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/AccountAdmin.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import edu.ksu.canvas.annotation.CanvasField; 4 | 5 | /** 6 | * Class to represent Canvas Account Admins. 7 | * See Admins documentation. 8 | */ 9 | public class AccountAdmin { 10 | public static final long serialVersionUID = 1L; 11 | 12 | private Long id; 13 | private String role; 14 | private Long roleId; 15 | private User user; 16 | private String workflowState; 17 | 18 | public Long getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Long id) { 23 | this.id = id; 24 | } 25 | 26 | public String getRole() { 27 | return role; 28 | } 29 | 30 | public void setRole(String role) { 31 | this.role = role; 32 | } 33 | 34 | public Long getRoleId() { 35 | return roleId; 36 | } 37 | 38 | public void setRoleId(Long roleId) { 39 | this.roleId = roleId; 40 | } 41 | 42 | public User getUser() { 43 | return user; 44 | } 45 | 46 | public void setUser(User user) { 47 | this.user = user; 48 | } 49 | 50 | @CanvasField(postKey = "workflow_state") 51 | public String getWorkflowState() { 52 | return workflowState; 53 | } 54 | 55 | public void setWorkflowState(String workflowState) { 56 | this.workflowState = workflowState; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/Deposit.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * This is part of the file upload workflow: https://canvas.instructure.com/doc/api/file.file_uploads.html 7 | * It's the data that is returned after asking to upload a file. 8 | */ 9 | public class Deposit { 10 | // This doesn't extend basemodel as it's never sent back to Canvas in the normal way. 11 | 12 | private String uploadUrl; 13 | private Map uploadParams; 14 | 15 | public String getUploadUrl() { 16 | return uploadUrl; 17 | } 18 | 19 | public void setUploadUrl(String uploadUrl) { 20 | this.uploadUrl = uploadUrl; 21 | } 22 | 23 | public Map getUploadParams() { 24 | return uploadParams; 25 | } 26 | 27 | public void setUploadParams(Map uploadParams) { 28 | this.uploadParams = uploadParams; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/FeatureFlag.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import java.io.Serializable; 4 | 5 | public class FeatureFlag implements Serializable { 6 | 7 | public enum State {on, off, allowed} 8 | 9 | private String contextType; 10 | private Long contextId; 11 | private String feature; 12 | private State state; 13 | 14 | public String getContextType() { 15 | return contextType; 16 | } 17 | 18 | public void setContextType(String contextType) { 19 | this.contextType = contextType; 20 | } 21 | 22 | public Long getContextId() { 23 | return contextId; 24 | } 25 | 26 | public void setContextId(Long contextId) { 27 | this.contextId = contextId; 28 | } 29 | 30 | public String getFeature() { 31 | return feature; 32 | } 33 | 34 | public void setFeature(String feature) { 35 | this.feature = feature; 36 | } 37 | 38 | public State getState() { 39 | return state; 40 | } 41 | 42 | public void setState(State state) { 43 | this.state = state; 44 | } 45 | 46 | public boolean isLocked() { 47 | return locked; 48 | } 49 | 50 | public void setLocked(boolean locked) { 51 | this.locked = locked; 52 | } 53 | 54 | private boolean locked; 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/Role.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import java.io.Serializable; 4 | 5 | import edu.ksu.canvas.annotation.CanvasObject; 6 | 7 | /** 8 | * Class to represent Canvas roles. 9 | * See Roles documentation. 10 | */ 11 | @CanvasObject(postKey = "role") 12 | public class Role extends BaseCanvasModel implements Serializable { 13 | private static final long serialVersionUID = 1L; 14 | 15 | private long id; 16 | private String label; 17 | private String baseRoleType; 18 | 19 | public long getId() { 20 | return id; 21 | } 22 | public void setId(long id) { 23 | this.id = id; 24 | } 25 | public String getLabel() { 26 | return label; 27 | } 28 | public void setLabel(String label) { 29 | this.label = label; 30 | } 31 | public String getBaseRoleType() { 32 | return baseRoleType; 33 | } 34 | public void setBaseRoleType(String baseRoleType) { 35 | this.baseRoleType = baseRoleType; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/UserDisplay.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Class to represent Canvas user mini-object. 7 | * See the Canvas User documentation. 8 | */ 9 | public class UserDisplay implements Serializable { 10 | public static final long serialVersionUID = 1L; 11 | 12 | private long id; 13 | private String displayName; 14 | private String avatarImageUrl; 15 | private String htmlUrl; 16 | 17 | public long getId() { 18 | return id; 19 | } 20 | 21 | public void setId(long id) { 22 | this.id = id; 23 | } 24 | 25 | public String getDisplayName() { 26 | return displayName; 27 | } 28 | 29 | public void setDisplayName(String displayName) { 30 | this.displayName = displayName; 31 | } 32 | 33 | public String getAvatarImageUrl() { 34 | return avatarImageUrl; 35 | } 36 | 37 | public void setAvatarImageUrl(String avatarImageUrl) { 38 | this.avatarImageUrl = avatarImageUrl; 39 | } 40 | 41 | public String getHtmlUrl() { 42 | return htmlUrl; 43 | } 44 | 45 | public void setHtmlUrl(String htmlUrl) { 46 | this.htmlUrl = htmlUrl; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/AssignmentDate.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * Class representing due dates for assignments and quizzes. 8 | * See API docs 9 | * 10 | */ 11 | public class AssignmentDate implements Serializable { 12 | private static final long serialVersionUID = 1L; 13 | 14 | private Long id; 15 | private String title; 16 | private Date dueAt; 17 | private Date unlockAt; 18 | private Date lockAt; 19 | private Boolean base; 20 | 21 | public Long getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Long id) { 26 | this.id = id; 27 | } 28 | 29 | public String getTitle() { 30 | return title; 31 | } 32 | 33 | public void setTitle(String title) { 34 | this.title = title; 35 | } 36 | 37 | public Date getDueAt() { 38 | return dueAt; 39 | } 40 | 41 | public void setDueAt(Date dueAt) { 42 | this.dueAt = dueAt; 43 | } 44 | 45 | public Date getUnlockAt() { 46 | return unlockAt; 47 | } 48 | 49 | public void setUnlockAt(Date unlockAt) { 50 | this.unlockAt = unlockAt; 51 | } 52 | 53 | public Date getLockAt() { 54 | return lockAt; 55 | } 56 | 57 | public void setLockAt(Date lockAt) { 58 | this.lockAt = lockAt; 59 | } 60 | 61 | public Boolean getBase() { 62 | return base; 63 | } 64 | 65 | public void setBase(Boolean base) { 66 | this.base = base; 67 | } 68 | } -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/GradingRules.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.BaseCanvasModel; 7 | 8 | /** 9 | * Object to represent Grading Rules which can optionally be embedded inside of an assignment group object 10 | */ 11 | public class GradingRules extends BaseCanvasModel implements Serializable { 12 | private static final long serialVersionUID = 1L; 13 | 14 | // Number of lowest scores to be dropped for each user. 15 | private Integer dropLowest; 16 | // Number of highest scores to be dropped for each user. 17 | private Integer dropHighest; 18 | // Assignment IDs that should never be dropped. 19 | private List neverDrop; 20 | 21 | public Integer getDropLowest() { 22 | return dropLowest; 23 | } 24 | 25 | public void setDropLowest(Integer dropLowest) { 26 | this.dropLowest = dropLowest; 27 | } 28 | 29 | public Integer getDropHighest() { 30 | return dropHighest; 31 | } 32 | 33 | public void setDropHighest(Integer dropHighest) { 34 | this.dropHighest = dropHighest; 35 | } 36 | 37 | public List getNeverDrop() { 38 | return neverDrop; 39 | } 40 | 41 | public void setNeverDrop(List neverDrop) { 42 | this.neverDrop = neverDrop; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/LockInfo.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | public class LockInfo implements Serializable { 7 | private static final long serialVersionUID = 1L; 8 | 9 | private String assetString; 10 | private Date unlockAt; 11 | private Date lockAt; 12 | private Object contextModule; //TODO: what is this object? a "module" as in this? https://canvas.instructure.com/doc/api/modules.html#Module 13 | private Boolean manuallyLocked; 14 | 15 | public String getAssetString() { 16 | return assetString; 17 | } 18 | 19 | public void setAssetString(String assetString) { 20 | this.assetString = assetString; 21 | } 22 | 23 | public Date getUnlockAt() { 24 | return unlockAt; 25 | } 26 | 27 | public void setUnlockAt(Date unlockAt) { 28 | this.unlockAt = unlockAt; 29 | } 30 | 31 | public Date getLockAt() { 32 | return lockAt; 33 | } 34 | 35 | public void setLockAt(Date lockAt) { 36 | this.lockAt = lockAt; 37 | } 38 | 39 | public Object getContextModule() { 40 | return contextModule; 41 | } 42 | 43 | public void setContextModule(Object contextModule) { 44 | this.contextModule = contextModule; 45 | } 46 | 47 | public Boolean getManuallyLocked() { 48 | return manuallyLocked; 49 | } 50 | 51 | public void setManuallyLocked(Boolean manuallyLocked) { 52 | this.manuallyLocked = manuallyLocked; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/MediaComment.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | import edu.ksu.canvas.model.BaseCanvasModel; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | * Object to represent a Media Comment which can optionally be embedded inside of a submission comment object 10 | */ 11 | public class MediaComment extends BaseCanvasModel implements Serializable { 12 | private static final long serialVersionUID = 1L; 13 | 14 | @SerializedName("content-type") //Needed because there is a dash instead of an underscore coming from Canvas 15 | private String contentType; 16 | private String displayName; 17 | private String mediaId; 18 | private String mediaType; 19 | private String url; 20 | 21 | public String getContentType() { 22 | return contentType; 23 | } 24 | 25 | public void setContentType(String contentType) { 26 | this.contentType = contentType; 27 | } 28 | 29 | public String getDisplayName() { 30 | return displayName; 31 | } 32 | 33 | public void setDisplayName(String displayName) { 34 | this.displayName = displayName; 35 | } 36 | 37 | public String getMediaId() { 38 | return mediaId; 39 | } 40 | 41 | public void setMediaId(String mediaId) { 42 | this.mediaId = mediaId; 43 | } 44 | 45 | public String getMediaType() { 46 | return mediaType; 47 | } 48 | 49 | public void setMediaType(String mediaType) { 50 | this.mediaType = mediaType; 51 | } 52 | 53 | public String getUrl() { 54 | return url; 55 | } 56 | 57 | public void setUrl(String url) { 58 | this.url = url; 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/QuizPermission.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Class to hold the permissions returned when querying quizzes. 7 | * Each one represents whether the user making the query has the permission described 8 | * See Canvas Quiz Permission documentation. 9 | */ 10 | 11 | public class QuizPermission implements Serializable { 12 | private static final long serialVersionUID = 1L; 13 | 14 | private Boolean read; 15 | private Boolean submit; 16 | private Boolean create; 17 | private Boolean manage; 18 | private Boolean readStatistics; 19 | private Boolean reviewGrades; 20 | private Boolean update; 21 | 22 | public Boolean canRead() { 23 | return read; 24 | } 25 | 26 | public Boolean canSubmit() { 27 | return submit; 28 | } 29 | 30 | public Boolean canCreate() { 31 | return create; 32 | } 33 | 34 | public Boolean canManage() { 35 | return manage; 36 | } 37 | 38 | public Boolean canReadStatistics() { 39 | return readStatistics; 40 | } 41 | 42 | public Boolean canReviewGrades() { 43 | return reviewGrades; 44 | } 45 | 46 | public Boolean canUpdate() { 47 | return update; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/QuizSubmissionQuestion.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Class to represent Canvas quiz submission question. 7 | * See Canvas Quiz Submission Question documentation. 8 | */ 9 | 10 | import java.util.List; 11 | 12 | public class QuizSubmissionQuestion implements Serializable { 13 | private static final long serialVersionUID = 1L; 14 | 15 | private Long id; 16 | private Boolean flagged; 17 | private List answer; //Set to JSON object, because it can either be an array or a String. 18 | private List answers; 19 | 20 | public Long getId() { 21 | return id; 22 | } 23 | 24 | public void setId(Long id) { 25 | this.id = id; 26 | } 27 | 28 | public Boolean getFlagged() { 29 | return flagged; 30 | } 31 | 32 | public void setFlagged(Boolean flagged) { 33 | this.flagged = flagged; 34 | } 35 | 36 | public List getAnswer() { 37 | return answer; 38 | } 39 | 40 | public void setAnswer(List answer) { 41 | this.answer = answer; 42 | } 43 | 44 | public List getAnswers() { 45 | return answers; 46 | } 47 | 48 | public void setAnswers(List answers) { 49 | this.answers = answers; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/assignment/RubricRating.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.assignment; 2 | 3 | import edu.ksu.canvas.model.BaseCanvasModel; 4 | 5 | import java.io.Serializable; 6 | 7 | public class RubricRating extends BaseCanvasModel implements Serializable { 8 | private static final long serialVersionUID = 1L; 9 | 10 | private String id; 11 | private String criterionId; 12 | private Double points; 13 | private String description; 14 | private String longDescription; 15 | 16 | public String getId() { 17 | return id; 18 | } 19 | 20 | public void setId(String id) { 21 | this.id = id; 22 | } 23 | 24 | public String getCriterionId() { 25 | return criterionId; 26 | } 27 | 28 | public void setCriterionId(String criterionId) { 29 | this.criterionId = criterionId; 30 | } 31 | 32 | public Double getPoints() { 33 | return points; 34 | } 35 | 36 | public void setPoints(Double points) { 37 | this.points = points; 38 | } 39 | 40 | public String getDescription() { 41 | return description; 42 | } 43 | 44 | public void setDescription(String description) { 45 | this.description = description; 46 | } 47 | 48 | public String getLongDescription() { 49 | return longDescription; 50 | } 51 | 52 | public void setLongDescription(String longDescription) { 53 | this.longDescription = longDescription; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * POJOs to parse Canvas API data into 3 | */ 4 | package edu.ksu.canvas.model; 5 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/report/AccountReportSummary.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.report; 2 | 3 | import java.io.Serializable; 4 | import java.util.Map; 5 | 6 | import edu.ksu.canvas.model.BaseCanvasModel; 7 | 8 | /** 9 | * A class to represent the top level report entity from Canvas. 10 | * See Account Reports#List Available Reports for more information. 11 | */ 12 | public class AccountReportSummary extends BaseCanvasModel implements Serializable { 13 | 14 | private String title; 15 | private Map parameters; 16 | private String report; 17 | private AccountReport lastRun; 18 | 19 | public String getTitle() { 20 | return title; 21 | } 22 | 23 | public void setTitle(String title) { 24 | this.title = title; 25 | } 26 | 27 | public Map getParameters() { 28 | return parameters; 29 | } 30 | 31 | public void setParameters(Map parameters) { 32 | this.parameters = parameters; 33 | } 34 | 35 | public String getReport() { 36 | return report; 37 | } 38 | 39 | public void setReport(String report) { 40 | this.report = report; 41 | } 42 | 43 | public AccountReport getLastRun() { 44 | return lastRun; 45 | } 46 | 47 | public void setLastRun(AccountReport lastRun) { 48 | this.lastRun = lastRun; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/status/CanvasErrorResponse.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.status; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Class to represent JSON error messages returned by Canvas. 7 | *

8 | * For some errors, Canvas returns JSON error strings that can be 9 | * parsed and displayed to the user. There isn't much documentation 10 | * on exactly how these messages are structured but here is an example 11 | * of something that is returned (along with an HTTP 400 in this case) 12 | * if a student tries to submit answers to a quiz that they are not 13 | * authorized to participate in: 14 | *

{"status":"bad_request","message":"you are not allowed to participate in this quiz","error_report_id":9005006}
15 | */ 16 | public class CanvasErrorResponse { 17 | 18 | private Long errorReportId; 19 | private String status; 20 | private List errors; 21 | 22 | public void setErrorReportId(Long errorReportId) { 23 | this.errorReportId = errorReportId; 24 | } 25 | 26 | public Long getErrorReportId() { 27 | return errorReportId; 28 | } 29 | 30 | public void setStatus(String status) { 31 | this.status = status; 32 | } 33 | 34 | public String getStatus() { 35 | return status; 36 | } 37 | 38 | public void setErrors(List errors) { 39 | this.errors = errors; 40 | } 41 | 42 | public List getErrors() { 43 | return errors; 44 | } 45 | 46 | public class ErrorMessage { 47 | private String message; 48 | 49 | public void setMessage(String message) { 50 | this.message = message; 51 | } 52 | 53 | public String getMessage() { 54 | return message; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/status/Conclude.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.status; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Class to parse the response on some object deletion methods. For certain 7 | * objects, such as courses, the Canvas API overloads the DELETE verb for 8 | * either true deletion or a "deleted" state such as conclusion, and returns 9 | * a response "conclude": true. 10 | */ 11 | public class Conclude implements Serializable { 12 | public static final long serialVersionUID = 1L; 13 | 14 | private Boolean conclude; 15 | 16 | public Boolean getConclude() { 17 | return conclude; 18 | } 19 | 20 | public void setConclude(Boolean conclude) { 21 | this.conclude = conclude; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/status/Delete.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.status; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * Class to parse the response on some object deletion methods. 7 | * Some deletion methods return the deleted object upon completion 8 | * but some return an object with just "deleted: true" in it. 9 | * 10 | */ 11 | public class Delete implements Serializable { 12 | public static final long serialVersionUID = 1L; 13 | 14 | private Boolean delete; 15 | 16 | public Boolean getDelete() { 17 | return delete; 18 | } 19 | 20 | public void setDelete(Boolean delete) { 21 | this.delete = delete; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/status/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Objects to represent Canvas status responses. 3 | *

4 | * Some API calls do not return Canvas domain objects but rather 5 | * a success/failure status or an error message. This package 6 | * contains objects to parse these responses. 7 | */ 8 | package edu.ksu.canvas.model.status; -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/wrapper/EnrollmentTermWrapper.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.wrapper; 2 | 3 | 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.EnrollmentTerm; 7 | 8 | /** 9 | * Wrapper class made necessary because canvas returns an object that 10 | * contains a list of EnrollmentTerm Objects, with only one item in the list. 11 | */ 12 | public class EnrollmentTermWrapper { 13 | 14 | private List enrollmentTerms; 15 | 16 | public List getEnrollmentTerms() { 17 | return enrollmentTerms; 18 | } 19 | 20 | public void setEnrollmentTerms(List enrollmentTerms) { 21 | this.enrollmentTerms = enrollmentTerms; 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/wrapper/QuizSubmissionQuestionWrapper.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.wrapper; 2 | 3 | import java.util.List; 4 | 5 | import edu.ksu.canvas.model.assignment.QuizSubmissionQuestion; 6 | 7 | /** 8 | * Wrapper class made necessary because canvas returns an object that 9 | * contains a list of QuizSubmissionQuestion Objects, with only one item in the list. 10 | * Rather than either just a list, or just the object.... 11 | */ 12 | public class QuizSubmissionQuestionWrapper { 13 | 14 | private List quizSubmissionQuestions; 15 | 16 | public List getQuizSubmissionQuestions() { 17 | return quizSubmissionQuestions; 18 | } 19 | 20 | public void setQuizsubmissionquestions(List quizSubmissionQuestions) { 21 | this.quizSubmissionQuestions = quizSubmissionQuestions; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/wrapper/QuizSubmissionWrapper.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model.wrapper; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import edu.ksu.canvas.model.User; 7 | import edu.ksu.canvas.model.assignment.Quiz; 8 | import edu.ksu.canvas.model.assignment.QuizSubmission; 9 | 10 | /** 11 | * Wrapper class made necessary because canvas returns an object that 12 | * contains a list of QuizSubmission objects, with supplemental objects 13 | */ 14 | public class QuizSubmissionWrapper { 15 | private List quizSubmissions = new ArrayList<>(); 16 | private List users = new ArrayList<>(); 17 | private List quizzes = new ArrayList<>(); 18 | 19 | public List getQuizSubmissions() { 20 | return quizSubmissions; 21 | } 22 | 23 | public void setQuizSubmissions(final List quizSubmissions) { 24 | this.quizSubmissions = quizSubmissions; 25 | } 26 | 27 | public List getUsers() { 28 | return users; 29 | } 30 | 31 | public void setUsers(final List users) { 32 | this.users = users; 33 | } 34 | 35 | public List getQuizzes() { 36 | return quizzes; 37 | } 38 | 39 | public void setQuizzes(List quizzes) { 40 | this.quizzes = quizzes; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/model/wrapper/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Wrapper objects for when the Canvas API returns lists wrapped in an object 3 | *

4 | * Some API calls return an object with a list inside of it instead of just 5 | * the list. The classes in here are just objects to hold lists for easy 6 | * parsing via Gson. They should only be used internally to the API library. 7 | */ 8 | package edu.ksu.canvas.model.wrapper; -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/net/ApiPost.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.net; 2 | 3 | import java.io.Serializable; 4 | import java.util.HashMap; 5 | 6 | public class ApiPost implements Serializable{ 7 | 8 | private static final long serialVersionUID = 1L; 9 | 10 | private String oauthToken; 11 | private String url; 12 | private String method; 13 | private HashMap postParameters; 14 | 15 | public ApiPost(String oauthToken, String url, String method, HashMap postParameters) { 16 | this.oauthToken = oauthToken; 17 | this.url = url; 18 | this.method = method; 19 | this.postParameters = postParameters; 20 | } 21 | 22 | public String getOauthToken() { 23 | return oauthToken; 24 | } 25 | 26 | public void setOauthToken(String oauthToken) { 27 | this.oauthToken = oauthToken; 28 | } 29 | 30 | public String getUrl() { 31 | return url; 32 | } 33 | 34 | public void setUrl(String url) { 35 | this.url = url; 36 | } 37 | 38 | public String getMethod() { 39 | return method; 40 | } 41 | 42 | public void setMethod(String method) { 43 | this.method = method; 44 | } 45 | 46 | public HashMap getPostParameters() { 47 | return postParameters; 48 | } 49 | 50 | public void setPostParameters(HashMap postParameters) { 51 | this.postParameters = postParameters; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/net/Response.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.net; 2 | 3 | public class Response { 4 | private boolean errorHappened = false; 5 | private int responseCode; 6 | private String nextLink; 7 | private String content; 8 | 9 | public boolean getErrorHappened() { 10 | return errorHappened; 11 | } 12 | 13 | public void setErrorHappened(boolean errorHappened) { 14 | this.errorHappened = errorHappened; 15 | } 16 | 17 | public int getResponseCode() { 18 | return responseCode; 19 | } 20 | 21 | public void setResponseCode(int responseCode) { 22 | this.responseCode = responseCode; 23 | } 24 | 25 | public String getNextLink() { 26 | return nextLink; 27 | } 28 | 29 | public void setNextLink(String nextLink) { 30 | this.nextLink = nextLink; 31 | } 32 | 33 | public String getContent() { 34 | return content; 35 | } 36 | 37 | public void setContent(String content) { 38 | this.content = content; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "Response{" + 44 | "errorHappened=" + errorHappened + 45 | ", responseCode=" + responseCode + 46 | ", nextLink='" + nextLink + '\'' + 47 | ", content='" + content + '\'' + 48 | '}'; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/net/RestClient.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.net; 2 | 3 | import edu.ksu.canvas.exception.InvalidOauthTokenException; 4 | import edu.ksu.canvas.oauth.OauthToken; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.util.List; 9 | import java.util.Map; 10 | 11 | import javax.validation.constraints.NotNull; 12 | 13 | public interface RestClient { 14 | Response sendApiGet(@NotNull OauthToken token, @NotNull String url, int connectTimeout, int readTimeout) throws IOException; 15 | Response sendJsonPost(@NotNull OauthToken token, @NotNull String url, String json, int connectTimeout, int readTimeout) throws IOException; 16 | Response sendJsonPut(@NotNull OauthToken token, @NotNull String url, String json, int connectTimeout, int readTimeout) throws IOException; 17 | Response sendApiPost(@NotNull OauthToken token, @NotNull String url, Map> postParameters, int connectTimeout, int readTimeout) throws InvalidOauthTokenException, IOException; 18 | Response sendApiPostFile(@NotNull OauthToken token, @NotNull String url, Map> postParameters, String fileParameter, String filePath, InputStream is, int connectTimeout, int readTimeout) throws InvalidOauthTokenException, IOException; 19 | Response sendApiDelete(@NotNull OauthToken token, @NotNull String url, Map> deleteParameters, int connectTimeout, int readTimeout) throws InvalidOauthTokenException, IOException; 20 | Response sendApiPut(@NotNull OauthToken token, @NotNull String url, Map> putParameters, int connectTimeout, int readTimeout) throws InvalidOauthTokenException, IOException; 21 | 22 | String sendUpload(String uploadUrl, Map> params, InputStream in, String filename, int connectTimeout, int readTimeout) throws IOException; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/net/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Classes dealing with low level network communications with the Canvas API. 3 | */ 4 | package edu.ksu.canvas.net; 5 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/oauth/NonRefreshableOauthToken.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.oauth; 2 | 3 | public class NonRefreshableOauthToken implements OauthToken { 4 | private static final long serialVersionUID = 1L; 5 | 6 | private String token; 7 | 8 | public NonRefreshableOauthToken(String token) { 9 | this.token = token; 10 | } 11 | @Override 12 | public String getAccessToken() { 13 | return token; 14 | } 15 | 16 | @Override 17 | public void refresh() { } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/oauth/OauthToken.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.oauth; 2 | 3 | import java.io.Serializable; 4 | 5 | public interface OauthToken extends Serializable { 6 | 7 | String getAccessToken(); 8 | 9 | void refresh(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/oauth/TokenRefreshResponse.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.oauth; 2 | 3 | /** 4 | * Object to represent the JSON received back from the call to get a new access token. 5 | */ 6 | public class TokenRefreshResponse { 7 | 8 | private String accessToken; 9 | private String tokenType; 10 | private Long expiresIn; 11 | private TokenUser user; 12 | 13 | public String getAccessToken() { 14 | return accessToken; 15 | } 16 | 17 | public void setAccessToken(String accessToken) { 18 | this.accessToken = accessToken; 19 | } 20 | 21 | public String getTokenType() { 22 | return tokenType; 23 | } 24 | 25 | public void setTokenType(String tokenType) { 26 | this.tokenType = tokenType; 27 | } 28 | 29 | public Long getExpiresIn() { 30 | if (expiresIn == null || expiresIn == 0) { 31 | return null; 32 | } 33 | return expiresIn; 34 | } 35 | 36 | public void setExpiresIn(Long expiresIn) { 37 | this.expiresIn = expiresIn; 38 | } 39 | 40 | public TokenUser getUser() { 41 | return user; 42 | } 43 | 44 | public void setUser(TokenUser user) { 45 | this.user = user; 46 | } 47 | 48 | public class TokenUser { 49 | private Long id; 50 | private String name; 51 | 52 | public Long getId() { 53 | return id; 54 | } 55 | 56 | public void setId(Long id) { 57 | this.id = id; 58 | } 59 | 60 | public String getName() { 61 | return name; 62 | } 63 | 64 | public void setName(String name) { 65 | this.name = name; 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/AnswerQuizQuestionOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class AnswerQuizQuestionOptions extends BaseOptions { 4 | 5 | private Long quizSubmissionId; 6 | 7 | /** 8 | * Create required API options for answering quiz questions 9 | * @param quizSubmissionId Quiz submission ID to submit answers to 10 | * @param attemptNumber Attempt number. Must be the latest attempt index since earlier ones can not be modified 11 | * @param validationToken Validation token returned by Canvas when the quiz submission was created 12 | */ 13 | public AnswerQuizQuestionOptions(Long quizSubmissionId, Long attemptNumber, String validationToken) { 14 | this.quizSubmissionId = quizSubmissionId; 15 | addSingleItem("attempt", attemptNumber.toString()); 16 | addSingleItem("validation_token", validationToken); 17 | } 18 | 19 | public Long getQuizSubmissionid() { 20 | return quizSubmissionId; 21 | } 22 | 23 | /** 24 | * If required, set an access code on this request 25 | * @param accessCode Access code set by the teacher on the quiz 26 | * @return This object to allow adding more options 27 | */ 28 | public AnswerQuizQuestionOptions accessCode(String accessCode) { 29 | addSingleItem("access_code", accessCode); 30 | return this; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/BaseOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.stream.Collectors; 9 | 10 | public abstract class BaseOptions { 11 | 12 | protected Map> optionsMap = new HashMap<>(); 13 | 14 | public Map> getOptionsMap() { 15 | return optionsMap; 16 | } 17 | 18 | /** 19 | * Add a list of enums to the options map 20 | * @param key The key for the options map (ex: "include[]") 21 | * @param list A list of enums 22 | */ 23 | protected void addEnumList(String key, List list) { 24 | optionsMap.put(key, list.stream().map(i -> i.toString()).collect(Collectors.toList())); 25 | } 26 | 27 | protected void addSingleItem(String key, String value) { 28 | optionsMap.put(key, Collections.singletonList(value)); 29 | } 30 | 31 | protected void addNumberList(String key, List list) { 32 | optionsMap.put(key, list.stream().map(i->i.toString()).collect(Collectors.toList())); 33 | } 34 | 35 | protected void addStringList(String key, List list) { 36 | optionsMap.put(key, new ArrayList(list)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/CreateCommunicationChannelOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import edu.ksu.canvas.model.CommunicationChannel; 4 | 5 | public class CreateCommunicationChannelOptions extends BaseOptions { 6 | 7 | protected final String userId; 8 | 9 | /** 10 | * Constructs object to hold API options for creating a communication channel. 11 | * @param userId The id of the related user 12 | */ 13 | public CreateCommunicationChannelOptions(String userId) { 14 | this.userId = userId; 15 | } 16 | 17 | public String getUserId() { 18 | return userId; 19 | } 20 | 21 | public CreateCommunicationChannelOptions skipConfirmation(Boolean skipConfirmation) { 22 | addSingleItem("skip_confirmation", skipConfirmation.toString()); 23 | return this; 24 | } 25 | 26 | public CreateCommunicationChannelOptions address(String address) { 27 | addSingleItem("communication_channel[address]", address); 28 | return this; 29 | } 30 | 31 | public CreateCommunicationChannelOptions type(CommunicationChannel.Type type) { 32 | addSingleItem("communication_channel[type]", type.toString()); 33 | return this; 34 | } 35 | 36 | public CreateCommunicationChannelOptions token(String token) { 37 | addSingleItem("communication_channel[token]", token); 38 | return this; 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/DeleteAssignmentGroupOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | public class DeleteAssignmentGroupOptions extends BaseOptions { 6 | 7 | private String courseId; 8 | private Long assignmentGroupId; 9 | 10 | public DeleteAssignmentGroupOptions(String courseId, Long assignmentGroupId) { 11 | if(StringUtils.isBlank(courseId) || assignmentGroupId == null || assignmentGroupId == 0) { 12 | throw new RuntimeException("Course ID and assignment group ID must be specified"); 13 | } 14 | this.courseId = courseId; 15 | this.assignmentGroupId = assignmentGroupId; 16 | } 17 | 18 | public String getCourseId() { 19 | return courseId; 20 | } 21 | 22 | public Long getAssignmentGroupId() { 23 | return assignmentGroupId; 24 | } 25 | 26 | /** 27 | * Optionally specify a new group to move assignments from the deleted group to. 28 | * @param newAssignmentGroupId ID of the target assignment group 29 | * @return this object to continue building options 30 | */ 31 | public DeleteAssignmentGroupOptions moveAssignmentsToGroup(Long newAssignmentGroupId) { 32 | addSingleItem("move_assignments_to", newAssignmentGroupId.toString()); 33 | return this; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/DeleteCalendarEventOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class DeleteCalendarEventOptions extends BaseOptions { 4 | 5 | private Long id; 6 | 7 | /** 8 | * @param id The calendar event to delete. 9 | */ 10 | public DeleteCalendarEventOptions(Long id) { 11 | this.id = id; 12 | } 13 | 14 | public Long getId() { 15 | return id; 16 | } 17 | 18 | public DeleteCalendarEventOptions cancelReason(String cancelReason) { 19 | addSingleItem("cancel_reason", cancelReason); 20 | return this; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/DeleteCourseOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | /** 4 | * Encapsulates the allowed input to the Canvas API DELETE call for courses. 5 | */ 6 | public class DeleteCourseOptions extends BaseOptions { 7 | 8 | /** 9 | * The event: whether we are deleting a course permanently, or marking it 10 | * as concluded. 11 | */ 12 | public enum EventType { 13 | 14 | DELETE, 15 | CONCLUDE; 16 | 17 | @Override 18 | public String toString() { 19 | return name().toLowerCase(); 20 | } 21 | } 22 | 23 | private final String courseId; 24 | 25 | private final EventType eventType; 26 | 27 | private String accountId; 28 | 29 | /** 30 | * Constructor. 31 | * 32 | * @param courseId identifies the course to delete 33 | * @param eventType whether to delete or conclude the course 34 | */ 35 | public DeleteCourseOptions(String courseId, EventType eventType) { 36 | this.courseId = courseId; 37 | this.eventType = eventType; 38 | addSingleItem("event", eventType.toString()); 39 | } 40 | 41 | public DeleteCourseOptions accountId(String accountId) { 42 | this.accountId = accountId; 43 | return this; 44 | } 45 | 46 | public String getCourseId() { 47 | return courseId; 48 | } 49 | 50 | public EventType getEventType() { 51 | return eventType; 52 | } 53 | 54 | public String getAccountId() { 55 | return accountId; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/GetEnrollmentTermOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | 4 | import java.util.List; 5 | 6 | public class GetEnrollmentTermOptions extends BaseOptions { 7 | 8 | private String accountId; 9 | 10 | public enum Include { 11 | OVERRIDES; 12 | 13 | @Override 14 | public String toString() { return name().toLowerCase(); } 15 | } 16 | 17 | /** 18 | * Create an options object for retrieving enrollment terms. Must have the account ID set. 19 | * @param accountID Required: ID of the canvas account. 20 | */ 21 | public GetEnrollmentTermOptions(String accountID) { 22 | this.accountId = accountID; 23 | } 24 | 25 | /** 26 | * Include additional optional fields in the enrollment term objects 27 | * @param includes List of additional fields to include 28 | * @return This object to allow adding more options 29 | */ 30 | public GetEnrollmentTermOptions includes(List includes) { 31 | addEnumList("include[]", includes); 32 | return this; 33 | } 34 | 35 | public String getAccountId() { return accountId; } 36 | 37 | 38 | } 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/GetQuizQuestionsOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class GetQuizQuestionsOptions extends BaseOptions { 4 | 5 | private String courseId; 6 | private Long quizId; 7 | 8 | public GetQuizQuestionsOptions(String courseId, Long quizId) { 9 | this.courseId = courseId; 10 | this.quizId = quizId; 11 | } 12 | 13 | public String getCourseId() { 14 | return courseId; 15 | } 16 | 17 | public Long getQuizId() { 18 | return quizId; 19 | } 20 | 21 | /** 22 | * If specified, this request will return the questions that were presented for the given submission. 23 | * Useful if the quiz was modified after the submission was created. 24 | * NOTE: If you specify this parameter, you MUST also specify the quizSubmissionAttempt. 25 | * @param submissionId Quiz Submission ID to get questions for 26 | * @return This object to allow adding more options 27 | */ 28 | public GetQuizQuestionsOptions quizSubmissionId(Long submissionId) { 29 | addSingleItem("quiz_submission_id", submissionId.toString()); 30 | return this; 31 | } 32 | 33 | /** 34 | * The attempt of the submission you want the questions for 35 | * @param submissionAttempt The ID of the submission attempt 36 | * @return This object to allow adding more options 37 | */ 38 | public GetQuizQuestionsOptions quizSubmissionAttempt(Long submissionAttempt) { 39 | addSingleItem("quiz_submission_attempt", submissionAttempt.toString()); 40 | return this; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/GetQuizSubmissionsOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import java.util.List; 6 | 7 | public class GetQuizSubmissionsOptions extends BaseOptions { 8 | private String courseId; 9 | private String quizId; 10 | 11 | public enum Include { 12 | // The canvas API gives a 3rd option here with a value of "submissions" but does not document what is 13 | // returned so I am not including it as an option until we can determine exactly what it is. 14 | USER, QUIZ; 15 | 16 | public String toString() { 17 | return name().toLowerCase(); 18 | } 19 | } 20 | 21 | /** 22 | * Optionally include more information with the returned Quiz Submission objects. 23 | * @param includes List of optional includes 24 | * @return This object to allow adding more options 25 | */ 26 | public GetQuizSubmissionsOptions includes(final List includes) { 27 | addEnumList("include[]", includes); 28 | return this; 29 | } 30 | 31 | public GetQuizSubmissionsOptions(final String courseId, final String quizId, final Include... includes) { 32 | this.courseId = courseId; 33 | this.quizId = quizId; 34 | if (includes.length > 0) { 35 | includes(ImmutableList.copyOf(includes)); 36 | } 37 | } 38 | 39 | public String getCourseId() { 40 | return courseId; 41 | } 42 | 43 | public void setCourseId(final String courseId) { 44 | this.courseId = courseId; 45 | } 46 | 47 | public String getQuizId() { 48 | return quizId; 49 | } 50 | 51 | public void setQuizId(final String quizId) { 52 | this.quizId = quizId; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/GetSelectiveDataOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class GetSelectiveDataOptions extends BaseOptions { 4 | 5 | private String itemId; 6 | private Long migrationId; 7 | private String type; 8 | 9 | /** 10 | * Constructs object to hold API options for the selective data calls. 11 | * 12 | * @param itemId The id of the item (course, user, group, account) involved in the migration process 13 | * @param migrationId The id of the migration 14 | * @param type Optional value for filtering the available selective data by type, i.e. assignments, quizzes, discussion_topics, etc. 15 | */ 16 | public GetSelectiveDataOptions(final String itemId, final Long migrationId, String type) { 17 | this.itemId = itemId; 18 | this.migrationId = migrationId; 19 | this.type = type; 20 | if(type != null) { 21 | addSingleItem("type", type); 22 | } 23 | } 24 | 25 | public String getItemId() { 26 | return itemId; 27 | } 28 | 29 | public void setItemId(final String itemId) { 30 | this.itemId = itemId; 31 | } 32 | 33 | public Long getMigrationId() { 34 | return migrationId; 35 | } 36 | 37 | public void setMigrationId(final Long migrationId) { 38 | this.migrationId = migrationId; 39 | } 40 | 41 | public String getType() { 42 | return type; 43 | } 44 | 45 | public void setType(String type) { 46 | this.type = type; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/GetSubAccountsOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class GetSubAccountsOptions extends BaseOptions { 4 | 5 | String accountId; 6 | 7 | public GetSubAccountsOptions(String accountId) { 8 | this.accountId = accountId; 9 | } 10 | 11 | public String getAccountId() { 12 | return accountId; 13 | } 14 | 15 | public GetSubAccountsOptions recursive(Boolean recursive) { 16 | addSingleItem("recursive", recursive.toString()); 17 | return this; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/ListAccountAdminsOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import java.util.List; 4 | 5 | public class ListAccountAdminsOptions extends BaseOptions { 6 | private String accountId; 7 | 8 | public ListAccountAdminsOptions(String accountId) { 9 | this.accountId = accountId; 10 | } 11 | 12 | public String getAccountId() { 13 | return accountId; 14 | } 15 | 16 | public ListAccountAdminsOptions includes(List userIds) { 17 | addStringList("user_id[]", userIds); 18 | return this; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/ListAccountOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import java.util.List; 4 | 5 | public class ListAccountOptions extends BaseOptions { 6 | 7 | public enum Include { 8 | LTI_GUID, REGISTRATION_SETTINGS; 9 | 10 | @Override 11 | public String toString() { return name().toLowerCase(); } 12 | } 13 | 14 | public ListAccountOptions includes(List includes) { 15 | addEnumList("include[]", includes); 16 | return this; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/ListModulesOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Options for listing the modules in a course. 7 | * 8 | * @see List modules 9 | */ 10 | public class ListModulesOptions extends BaseOptions { 11 | 12 | public enum Include { 13 | ITEMS, 14 | CONTENT_DETAILS 15 | } 16 | 17 | private Long courseId; 18 | 19 | public ListModulesOptions(Long courseId) { 20 | this.courseId = courseId; 21 | } 22 | 23 | public Long getCourseId() { 24 | return courseId; 25 | } 26 | 27 | public ListModulesOptions includes(List includes) { 28 | addEnumList("include[]", includes); 29 | return this; 30 | } 31 | 32 | public ListModulesOptions searchTerm(String searchTerm) { 33 | addSingleItem("search_term", searchTerm); 34 | return this; 35 | } 36 | 37 | public ListModulesOptions studentId(String studentId) { 38 | addSingleItem("student_id", studentId); 39 | return this; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/ListRolesOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * A class to represent parameters to be passed to the "List the roles available to an account" API call. 7 | * See 8 | * https://canvas.instructure.com/doc/api/roles.html#method.role_overrides.api_index 9 | */ 10 | public class ListRolesOptions extends BaseOptions { 11 | 12 | private String accountId; 13 | 14 | public enum State { 15 | ACTIVE, INACTIVE; 16 | @Override 17 | public String toString() { return name().toLowerCase(); } 18 | } 19 | 20 | public ListRolesOptions(String accountId) { 21 | this.accountId = accountId; 22 | } 23 | 24 | public String getAccountId() { 25 | return accountId; 26 | } 27 | 28 | /** 29 | * If set to true, inherited roles from parent accounts will be included 30 | * @param show Whether or not to include inherited roles 31 | * @return This object to allow adding more options 32 | */ 33 | public ListRolesOptions showInherited(Boolean show) { 34 | if( show != null ) { 35 | addSingleItem("show_inherited", show.toString()); 36 | } 37 | return this; 38 | } 39 | 40 | /** 41 | * Filter returned roles by activity state. Default is only "active" roles 42 | * @param states List of states to filter by (active or inactive) 43 | * @return This object to allow adding more options 44 | */ 45 | public ListRolesOptions state(List states) { 46 | addEnumList("state[]", states); 47 | return this; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/ListUserAssignmentOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | /** 4 | * Class for capturing options passed to the "List assignments for user" API call 5 | * The options are identical to the "List assignments for course" call except 6 | * the additional user ID parameter is required. 7 | */ 8 | public class ListUserAssignmentOptions extends ListCourseAssignmentsOptions { 9 | private String userId; 10 | 11 | public ListUserAssignmentOptions(String courseId, String userId) { 12 | super(courseId); 13 | this.userId = userId; 14 | } 15 | 16 | public String getUserId() { 17 | return userId; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/StartQuizSubmissionOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | public class StartQuizSubmissionOptions extends BaseOptions { 4 | 5 | private String courseId; 6 | private Long quizId; 7 | 8 | /** 9 | * Create API options wrapper for the "create quiz submission" API call with required parameters 10 | * @param courseId Course ID of the course the quiz is in 11 | * @param quizId Quiz ID of the quiz that is being taken 12 | */ 13 | public StartQuizSubmissionOptions(String courseId, Long quizId) { 14 | this.courseId = courseId; 15 | this.quizId = quizId; 16 | } 17 | 18 | public String getCourseId() { 19 | return courseId; 20 | } 21 | 22 | public Long getQuizId() { 23 | return quizId; 24 | } 25 | 26 | /** 27 | * Add an access code (if required) 28 | * @param accessCode The access code set by the instructor 29 | * @return This object to allow adding more options 30 | */ 31 | public StartQuizSubmissionOptions accessCode(String accessCode) { 32 | addSingleItem("access_code", accessCode); 33 | return this; 34 | } 35 | 36 | /** 37 | * Only valid for teachers. Set whether this should be a preview submission and not count towards the user's course record. 38 | * @param preview Whether this should be a preview 39 | * @return This object to allow adding more options 40 | */ 41 | public StartQuizSubmissionOptions preview(Boolean preview) { 42 | addSingleItem("preview", preview.toString()); 43 | return this; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/UnEnrollOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | 4 | /** 5 | * 6 | * UnEnrollOptions denote the canvas Enrollment dropUser's task request parameter supported values. See 7 | * https://canvas.instructure.com/doc/api/enrollments.html#method.enrollments_api.destroy 8 | * for a discussion of these. 9 | */ 10 | public enum UnEnrollOptions { 11 | DELETE("delete"), 12 | CONCLUDE("conclude"), 13 | INACTIVATE("inactivate"), 14 | DEACTIVATE("deactivate"); 15 | 16 | private String canvasValue; 17 | 18 | UnEnrollOptions(String canvasValue) {this.canvasValue = canvasValue;} 19 | 20 | @Override 21 | public String toString() { 22 | return canvasValue; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/UpdateCourseTabOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | /** 4 | * Options for updating a tab for a given course. 5 | */ 6 | public class UpdateCourseTabOptions extends BaseOptions { 7 | 8 | private String courseId; 9 | 10 | private String tabId; 11 | 12 | private long position; 13 | 14 | private boolean hidden; 15 | 16 | /** 17 | * Constructor. 18 | * 19 | * @param courseId identifies the course 20 | * @param tabId identifies the tab within the course 21 | */ 22 | public UpdateCourseTabOptions(String courseId, String tabId) { 23 | this.courseId = courseId; 24 | this.tabId = tabId; 25 | } 26 | 27 | /** 28 | * Sets the position (1-based). 29 | * @param position The new position of the tab (1-based) 30 | * @return This object to continue adding options 31 | */ 32 | public UpdateCourseTabOptions position(long position) { 33 | addSingleItem("position", Long.toString(position)); 34 | return this; 35 | } 36 | 37 | public UpdateCourseTabOptions hidden(boolean hidden) { 38 | addSingleItem("hidden", Boolean.toString(hidden)); 39 | return this; 40 | } 41 | 42 | public String getCourseId() { 43 | return courseId; 44 | } 45 | 46 | public String getTabId() { 47 | return tabId; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/UploadOptions.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.requestOptions; 2 | 3 | /** 4 | * The options needed when uploading a file: https://canvas.instructure.com/doc/api/file.file_uploads.html 5 | */ 6 | public class UploadOptions extends BaseOptions { 7 | 8 | public UploadOptions(String name) { 9 | addSingleItem("name", name); 10 | } 11 | 12 | public UploadOptions size(long size) { 13 | addSingleItem("size", Long.toString(size)); 14 | return this; 15 | } 16 | 17 | public UploadOptions contentType(String contentType) { 18 | addSingleItem("content_type", contentType); 19 | return this; 20 | } 21 | 22 | public UploadOptions parentFolderId(long parentFolderId) { 23 | addSingleItem("parent_folder_id", Long.toString(parentFolderId)); 24 | return this; 25 | } 26 | 27 | public UploadOptions parentFolderPath(String parentFolderPath) { 28 | addSingleItem("parent_folder_path", parentFolderPath); 29 | return this; 30 | } 31 | 32 | public UploadOptions onDuplicateRename() { 33 | addSingleItem("on_duplicate", "rename"); 34 | return this; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/requestOptions/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Classes to encapsulate parameters that get passed to API calls. 3 | *

4 | * Some API calls take a huge list of (often optional) parameters. The 5 | * classes in this package allow type-safe usage of these parameters 6 | * and allow new parameters to be added without breaking existing code. 7 | */ 8 | package edu.ksu.canvas.requestOptions; -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/util/CanvasURLBuilder.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.util; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.util.Map; 7 | import java.util.List; 8 | 9 | 10 | public class CanvasURLBuilder { 11 | private static final Logger LOG = LoggerFactory.getLogger(CanvasURLBuilder.class); 12 | 13 | /* Builds parameters in form of ?param[]=value1¶m[]=value2&otherParam=someValue*/ 14 | public static String buildCanvasUrl(String canvasBaseUrl, int canvasAPIVersion, String canvasMethod, Map> parameters) { 15 | canvasMethod = removeForwardSlashIfExists(canvasMethod); 16 | String url = canvasBaseUrl + "/api/v" + canvasAPIVersion + "/" + canvasMethod; 17 | String finalUrl = url + HttpParameterBuilder.buildParameters(parameters); 18 | LOG.debug("Built Canvas url - " + finalUrl); 19 | return finalUrl; 20 | } 21 | 22 | private static String removeForwardSlashIfExists(String canvasMethod) { 23 | int beginIndex = canvasMethod.startsWith("/") ? 1 : 0; 24 | int endIndex = canvasMethod.endsWith("/") ? canvasMethod.length() - 1 : canvasMethod.length(); 25 | 26 | return canvasMethod.substring(beginIndex, endIndex); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/util/KeyFirstComparator.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.util; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Needed to put the key as the first parameter in the map which is needed for AWS S3 uploads 7 | */ 8 | public class KeyFirstComparator implements Comparator { 9 | 10 | public static final String KEY = "key"; 11 | 12 | @Override 13 | public int compare(String o1, String o2) { 14 | if (KEY.equals(o1)) { 15 | return -1; 16 | } 17 | if (KEY.equals(o2)) { 18 | return 1; 19 | } 20 | return o1.compareTo(o2); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/edu/ksu/canvas/util/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * This package provides common utility functions to reduce code duplication 3 | * for things like building API URLs. 4 | */ 5 | package edu.ksu.canvas.util; 6 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/CanvasTestBase.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas; 2 | 3 | import edu.ksu.canvas.config.CommonTestConfig; 4 | import edu.ksu.canvas.interfaces.CanvasMessenger; 5 | import edu.ksu.canvas.net.FakeRestClient; 6 | import edu.ksu.canvas.oauth.NonRefreshableOauthToken; 7 | import edu.ksu.canvas.oauth.OauthToken; 8 | 9 | import org.junit.runner.RunWith; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.test.context.ActiveProfiles; 12 | import org.springframework.test.context.ContextConfiguration; 13 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 14 | 15 | @RunWith(SpringJUnit4ClassRunner.class) 16 | @ContextConfiguration(classes = {CommonTestConfig.class}) 17 | @ActiveProfiles("dev") 18 | public abstract class CanvasTestBase { 19 | public static final OauthToken SOME_OAUTH_TOKEN = new NonRefreshableOauthToken("token");; 20 | public static final int SOME_CONNECT_TIMEOUT = 1000; 21 | public static final int SOME_READ_TIMEOUT = 1000; 22 | public static final Integer DEFAULT_PAGINATION_PAGE_SIZE = null; 23 | @Autowired 24 | protected CanvasMessenger mockCanvasMessenger; 25 | @Autowired 26 | protected String baseUrl; 27 | @Autowired 28 | protected FakeRestClient fakeRestClient; 29 | protected Integer apiVersion = 1; 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/LocalServerTestBase.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas; 2 | 3 | import edu.ksu.canvas.net.SimpleRestClientUTest; 4 | import edu.ksu.canvas.util.JsonTestUtil; 5 | import org.apache.http.HttpHost; 6 | import org.apache.http.entity.StringEntity; 7 | import org.junit.After; 8 | import org.junit.Before; 9 | 10 | import java.util.Map; 11 | 12 | /** 13 | * Base test class for classes that need a LocalTestServer to simulate 14 | * network traffic 15 | */ 16 | public class LocalServerTestBase extends org.apache.http.localserver.LocalServerTestBase{ 17 | protected String baseUrl; 18 | protected HttpHost httpHost; 19 | 20 | @Before 21 | public void setUp() throws Exception { 22 | super.setUp(); 23 | } 24 | 25 | @After 26 | public void tearDown() throws Exception { 27 | server.stop(); 28 | super.shutDown(); 29 | } 30 | 31 | protected void registerUrlResponse(String url, String sampleJsonFileName, Integer statusCode, Map headers) throws Exception { 32 | String jsonContent = JsonTestUtil.loadJson(sampleJsonFileName, SimpleRestClientUTest.class); 33 | serverBootstrap.registerHandler(url, (request, response, context) -> { 34 | response.setStatusCode(statusCode); 35 | for(String key : headers.keySet()) { 36 | String value = headers.get(key); 37 | response.addHeader(key, value); 38 | } 39 | response.setEntity(new StringEntity(jsonContent)); 40 | }); 41 | httpHost = super.start(); 42 | baseUrl = httpHost.toURI(); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/TestCanvasReader.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas; 2 | 3 | import edu.ksu.canvas.interfaces.CanvasReader; 4 | import edu.ksu.canvas.model.TestCanvasModel; 5 | 6 | import java.io.IOException; 7 | import java.util.List; 8 | import java.util.Optional; 9 | 10 | public interface TestCanvasReader extends CanvasReader { 11 | List getTestModels(String url) throws IOException; 12 | Optional getTestModel(String url) throws IOException; 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/TestCanvasReaderImpl.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas; 2 | 3 | import com.google.gson.reflect.TypeToken; 4 | import edu.ksu.canvas.impl.BaseImpl; 5 | import edu.ksu.canvas.model.TestCanvasModel; 6 | import edu.ksu.canvas.net.RestClient; 7 | import edu.ksu.canvas.oauth.OauthToken; 8 | 9 | import java.io.IOException; 10 | import java.lang.reflect.Type; 11 | import java.util.List; 12 | import java.util.Optional; 13 | 14 | public class TestCanvasReaderImpl extends BaseImpl implements TestCanvasReader { 15 | 16 | public TestCanvasReaderImpl(String canvasBaseUrl, Integer apiVersion, OauthToken oauthToken, RestClient restClient, int connectTimeout, int readTimeout) { 17 | super(canvasBaseUrl, apiVersion, oauthToken, restClient, connectTimeout, readTimeout, CanvasTestBase.DEFAULT_PAGINATION_PAGE_SIZE, false); 18 | } 19 | 20 | public List getTestModels(String url) throws IOException { 21 | return getListFromCanvas(url); 22 | } 23 | 24 | public Optional getTestModel(String url) throws IOException { 25 | return getFromCanvas(url); 26 | } 27 | 28 | @Override 29 | protected Type listType() { 30 | return new TypeToken>(){}.getType(); 31 | } 32 | 33 | @Override 34 | protected Class objectType() { 35 | return TestCanvasModel.class; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/TestCanvasWriter.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas; 2 | 3 | import edu.ksu.canvas.interfaces.CanvasWriter; 4 | import edu.ksu.canvas.model.TestCanvasModel; 5 | 6 | public interface TestCanvasWriter extends CanvasWriter { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/config/BaseTestConfig.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.config; 2 | 3 | import edu.ksu.canvas.net.FakeRestClient; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Profile; 8 | 9 | @Configuration 10 | @Profile("dev") 11 | @ComponentScan({"edu.ksu.canvas"}) 12 | public class BaseTestConfig { 13 | @Bean 14 | public FakeRestClient fakeRestClient() { 15 | return new FakeRestClient(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/config/CommonTestConfig.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.config; 2 | 3 | import edu.ksu.canvas.impl.GsonResponseParser; 4 | import edu.ksu.canvas.impl.RestCanvasMessenger; 5 | import edu.ksu.canvas.net.FakeRestClient; 6 | import edu.ksu.canvas.interfaces.CanvasMessenger; 7 | import edu.ksu.canvas.interfaces.ResponseParser; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.context.annotation.Profile; 12 | 13 | 14 | @Configuration 15 | @ComponentScan({"edu.ksu.canvas"}) 16 | @Profile("dev") 17 | public class CommonTestConfig { 18 | public static final int API_VERSION = 1; 19 | @Bean 20 | public String canvasBaseUrl() { 21 | return "domain"; 22 | } 23 | 24 | @Bean(name = "restClient") 25 | public FakeRestClient restClient() { 26 | return new FakeRestClient(); 27 | } 28 | 29 | @Bean(name = "canvasMessenger") 30 | public CanvasMessenger canvasMessenger() { 31 | return new RestCanvasMessenger(FakeRestClient.NO_TIMEOUT, FakeRestClient.NO_TIMEOUT, restClient()); 32 | } 33 | 34 | @Bean(name = "canvasResponseParser") 35 | public ResponseParser canvasResponseParser() { 36 | return new GsonResponseParser(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/impl/GsonResponseParserInstantTest.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.impl; 2 | 3 | import com.google.gson.Gson; 4 | import junit.framework.TestCase; 5 | 6 | import java.time.Instant; 7 | 8 | public class GsonResponseParserInstantTest extends TestCase { 9 | 10 | /** 11 | * Simple helper to make JSON literals easier to write in Java 12 | * 13 | * @param json JSON with ' as the string quote character. 14 | * @return JSON with " as the string quote character. 15 | */ 16 | static String quote(String json) { 17 | return json.replace("'", "\""); 18 | } 19 | 20 | public void testInstantParsingNoZone() { 21 | Gson defaultGsonParser = GsonResponseParser.getDefaultGsonParser(false); 22 | Sample sample = defaultGsonParser.fromJson(quote("{'instant': '2020-02-20T01:02:03Z'}"), Sample.class); 23 | assertNotNull(sample); 24 | assertEquals(Instant.parse("2020-02-20T01:02:03Z"), sample.instant); 25 | } 26 | 27 | public void testInstantParsingZone() { 28 | Gson defaultGsonParser = GsonResponseParser.getDefaultGsonParser(false); 29 | Sample sample = defaultGsonParser.fromJson(quote("{'instant': '2020-02-20T01:02:03-04:00'}"), Sample.class); 30 | assertNotNull(sample); 31 | assertEquals(Instant.parse("2020-02-20T05:02:03Z"), sample.instant); 32 | } 33 | 34 | public void testInstantParsingZonePositive() { 35 | Gson defaultGsonParser = GsonResponseParser.getDefaultGsonParser(false); 36 | Sample sample = defaultGsonParser.fromJson(quote("{'instant': '2020-02-20T01:02:03+04:00'}"), Sample.class); 37 | assertNotNull(sample); 38 | assertEquals(Instant.parse("2020-02-19T21:02:03Z"), sample.instant); 39 | } 40 | 41 | static class Sample { 42 | public Instant instant; 43 | } 44 | } -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/model/CalendarEventTest.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.model; 2 | 3 | import org.junit.Test; 4 | 5 | import java.time.Instant; 6 | import java.util.Collections; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class CalendarEventTest { 11 | 12 | @Test 13 | public void testCopyConstructorEmpty() { 14 | CalendarEvent event = new CalendarEvent(); 15 | CalendarEvent other = new CalendarEvent(event); 16 | assertEquals(event, other); 17 | } 18 | 19 | @Test 20 | public void testCopyConstructorCreationFields() { 21 | CalendarEvent event = new CalendarEvent(); 22 | event.setId(1L); 23 | event.setTitle("Title"); 24 | event.setStartAt(Instant.now()); 25 | event.setEndAt(Instant.now()); 26 | event.setDescription("The description"); 27 | event.setLocationName("Location name"); 28 | event.setLocationAddress("Location address"); 29 | event.setContextCode("context_code"); 30 | { 31 | CalendarEvent.ChildEvent child = new CalendarEvent.ChildEvent(); 32 | child.setContextCode("context_code"); 33 | child.setStartAt(Instant.now()); 34 | child.setEndAt(Instant.now()); 35 | event.setChildEventsData(Collections.singletonList(child)); 36 | } 37 | 38 | CalendarEvent other = new CalendarEvent(event); 39 | assertEquals(event, other); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/tests/roles/RolesUTest.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.tests.roles; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | import edu.ksu.canvas.CanvasTestBase; 11 | import edu.ksu.canvas.impl.RoleImpl; 12 | import edu.ksu.canvas.interfaces.RoleReader; 13 | import edu.ksu.canvas.model.Role; 14 | import edu.ksu.canvas.net.FakeRestClient; 15 | import edu.ksu.canvas.requestOptions.ListRolesOptions; 16 | import edu.ksu.canvas.util.CanvasURLBuilder; 17 | 18 | public class RolesUTest extends CanvasTestBase { 19 | @Autowired 20 | private FakeRestClient fakeRestClient; 21 | private RoleReader roleReader; 22 | 23 | private static final String ROOT_ACCOUNT_ID = "1"; 24 | 25 | @Before 26 | public void setupReader() { 27 | roleReader = new RoleImpl(baseUrl, apiVersion, SOME_OAUTH_TOKEN, fakeRestClient, SOME_CONNECT_TIMEOUT, 28 | SOME_READ_TIMEOUT, DEFAULT_PAGINATION_PAGE_SIZE, false); 29 | } 30 | 31 | @Test 32 | public void testListRoles() throws Exception { 33 | ListRolesOptions options = new ListRolesOptions(ROOT_ACCOUNT_ID); 34 | String url = CanvasURLBuilder.buildCanvasUrl(baseUrl, apiVersion,"accounts/" + options.getAccountId() + "/roles", options.getOptionsMap()); 35 | fakeRestClient.addSuccessResponse(url, "SampleJson/role/Role.json"); 36 | List rolesList = roleReader.listRoles(options); 37 | Assert.assertNotNull(rolesList); 38 | Assert.assertEquals(1, rolesList.size()); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/tests/tab/TabUTest.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.tests.tab; 2 | 3 | import java.io.IOException; 4 | import java.util.Optional; 5 | 6 | import edu.ksu.canvas.CanvasTestBase; 7 | import edu.ksu.canvas.impl.TabImpl; 8 | import edu.ksu.canvas.interfaces.TabWriter; 9 | import edu.ksu.canvas.model.Tab; 10 | import edu.ksu.canvas.net.FakeRestClient; 11 | import edu.ksu.canvas.requestOptions.UpdateCourseTabOptions; 12 | import org.junit.Before; 13 | import org.junit.Test; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | 16 | import static org.junit.Assert.assertEquals; 17 | import static org.junit.Assert.assertTrue; 18 | 19 | public class TabUTest extends CanvasTestBase { 20 | 21 | @Autowired 22 | private FakeRestClient fakeRestClient; 23 | 24 | private TabWriter tabWriter; 25 | 26 | @Before 27 | public void setUp() { 28 | tabWriter = new TabImpl(baseUrl, apiVersion, SOME_OAUTH_TOKEN, fakeRestClient, SOME_CONNECT_TIMEOUT, 29 | SOME_READ_TIMEOUT, DEFAULT_PAGINATION_PAGE_SIZE, false); 30 | } 31 | 32 | @Test 33 | public void testUpdateCourseTab() throws IOException { 34 | String url = baseUrl + "/api/v1/courses/1234/tabs/files"; 35 | fakeRestClient.addSuccessResponse(url, "SampleJson/tab/UpdateTabSuccess.json"); 36 | UpdateCourseTabOptions options = new UpdateCourseTabOptions("1234", "files"); 37 | options.hidden(true); 38 | Optional tab = tabWriter.updateCourseTab(options); 39 | 40 | assertTrue(tab.isPresent()); 41 | assertEquals("files", tab.get().getId()); 42 | assertTrue(tab.get().isHidden()); 43 | assertEquals("admins", tab.get().getVisibility()); 44 | assertEquals("Files", tab.get().getLabel()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/edu/ksu/canvas/util/JsonTestUtil.java: -------------------------------------------------------------------------------- 1 | package edu.ksu.canvas.util; 2 | 3 | 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | import java.io.InputStream; 8 | 9 | public class JsonTestUtil { 10 | private static final Logger LOG = LoggerFactory.getLogger(JsonTestUtil.class); 11 | public static String loadJson(String fileName, Class clazz) { 12 | try { 13 | InputStream stream = clazz.getResourceAsStream(fileName); 14 | int c = (char) stream.read(); 15 | String json = ""; 16 | while (c != -1) { 17 | json += (char) c; 18 | c = stream.read(); 19 | } 20 | return json; 21 | } catch (Exception e) { 22 | LOG.error("Could not load json file " + fileName,e); 23 | return null; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/test/resources/InvalidJson.json: -------------------------------------------------------------------------------- 1 | This json is invalid -------------------------------------------------------------------------------- /src/test/resources/SampleJson/BlankResponse.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /src/test/resources/SampleJson/CreateUserResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 78852, 3 | "name": "somestring4", 4 | "sortable_name": "somestring4", 5 | "short_name": "somestring4", 6 | "login_id": "somestring4", 7 | "locale": null, 8 | "confirmation_url": "https://instance.test.instructure.com/register/214b60f3e9c42873d323bd503f9afd4e" 9 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/EnrollmentDeleteResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "associated_user_id": null, 3 | "course_id": 25, 4 | "course_section_id": 36, 5 | "created_at": "2015-10-08T16:50:38Z", 6 | "end_at": null, 7 | "id": 355047, 8 | "limit_privileges_to_course_section": false, 9 | "root_account_id": 1, 10 | "start_at": null, 11 | "type": "StudentEnrollment", 12 | "updated_at": "2015-10-08T16:54:34Z", 13 | "user_id": 78839, 14 | "enrollment_state": "deleted", 15 | "role": "StudentEnrollment", 16 | "role_id": 80, 17 | "last_activity_at": null, 18 | "total_activity_time": 0, 19 | "sis_import_id": null, 20 | "grades": { 21 | "html_url": "http://canvas.example.edu/courses/25/grades/78839", 22 | "current_score": null, 23 | "final_score": null, 24 | "current_grade": null, 25 | "final_grade": null 26 | }, 27 | "sis_source_id": null, 28 | "sis_course_id": "12345", 29 | "course_integration_id": null, 30 | "sis_section_id": null, 31 | "section_integration_id": null, 32 | "html_url": "http://canvas.example.edu/courses/25/users/78839" 33 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/EnrollmentResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "associated_user_id": null, 3 | "course_id": 25, 4 | "course_section_id": 36, 5 | "created_at": "2015-10-08T16:50:38Z", 6 | "end_at": null, 7 | "id": 355047, 8 | "limit_privileges_to_course_section": false, 9 | "root_account_id": 1, 10 | "start_at": null, 11 | "type": "StudentEnrollment", 12 | "updated_at": "2015-10-08T16:50:38Z", 13 | "user_id": 78839, 14 | "enrollment_state": "invited", 15 | "role": "StudentEnrollment", 16 | "role_id": 80, 17 | "last_activity_at": null, 18 | "total_activity_time": 0, 19 | "sis_import_id": null, 20 | "grades": { 21 | "html_url": "http://canvas.example.edu/courses/25/grades/78839", 22 | "current_score": null, 23 | "final_score": null, 24 | "current_grade": null, 25 | "final_grade": null 26 | }, 27 | "sis_source_id": null, 28 | "sis_course_id": "12345", 29 | "course_integration_id": null, 30 | "sis_section_id": null, 31 | "section_integration_id": null, 32 | "html_url": "http://canvas.example.edu/courses/25/users/78839" 33 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/EnrollmentTerm.json: -------------------------------------------------------------------------------- 1 | { 2 | "enrollment_terms":[ 3 | { 4 | "id": 1, 5 | "name": "Fall 2016", 6 | "start_at": "2016-08-31T20:00:00Z", 7 | "end_at": "2016-12-20T20:00:00Z", 8 | "created_at": "2016-07-16T20:00:00Z", 9 | "workflow_state": "active", 10 | "grading_period_group_id": null, 11 | "sis_term_id": "81" 12 | } 13 | ] 14 | } 15 | 16 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/Modules.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 41188, 4 | "name": "Module One", 5 | "position": 1, 6 | "unlock_at": null, 7 | "require_sequential_progress": false, 8 | "publish_final_grade": false, 9 | "prerequisite_module_ids": [], 10 | "state": "completed", 11 | "completed_at": "2020-02-11T00:00:27Z", 12 | "published": true, 13 | "items_count": 1, 14 | "items_url": "https://canvas.example.edu/api/v1/courses/1092/modules/41188/items" 15 | }, 16 | { 17 | "id": 239752, 18 | "name": "Module Two", 19 | "position": 2, 20 | "unlock_at": null, 21 | "require_sequential_progress": false, 22 | "publish_final_grade": false, 23 | "prerequisite_module_ids": [], 24 | "state": "unlocked", 25 | "completed_at": null, 26 | "published": true, 27 | "items_count": 1, 28 | "items_url": "https://canvas.example.edu/api/v1/courses/1092/modules/239752/items" 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/Progress.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 61111111, 3 | "context_id": 37836, 4 | "context_type": "Course", 5 | "user_id": null, 6 | "tag": "submissions_update", 7 | "completion": null, 8 | "workflow_state": "queued", 9 | "created_at": "2017-04-14T14:32:18Z", 10 | "updated_at": "2017-04-14T14:32:18Z", 11 | "message": null, 12 | "url": "canvas.example.edu/api/v1/progress/61111111" 13 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/account/AccountWithLtiGuid.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Kansas State University", 5 | "workflow_state": "active", 6 | "parent_account_id": null, 7 | "root_account_id": null, 8 | "default_storage_quota_mb": 5000, 9 | "default_user_storage_quota_mb": 5000, 10 | "default_group_storage_quota_mb": 1000, 11 | "default_time_zone": "America/Chicago", 12 | "lti_guid": "f22a4332-3d40-427b-846d-9bc1fa5ab9b4.canvas.example.edu" 13 | } 14 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/account/RootAccount.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Kansas State University", 4 | "workflow_state": "active", 5 | "parent_account_id": null, 6 | "root_account_id": null, 7 | "default_storage_quota_mb": 5000, 8 | "default_user_storage_quota_mb": 5000, 9 | "default_group_storage_quota_mb": 1000, 10 | "default_time_zone": "America/Chicago" 11 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/accountReport/SingleAccountReportListing.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 2, 3 | "progress": 50, 4 | "parameters": { 5 | "enrollment_term_id": "", 6 | "enrollments": "1", 7 | "extra_text": "Term: All Terms; Reports: enrollments " 8 | }, 9 | "current_line": 25000, 10 | "status": "running", 11 | "report": "sis_export_csv", 12 | "created_at": "2018-05-11T08:30:39-06:00", 13 | "started_at": "2018-05-11T08:30:40-06:00", 14 | "ended_at": null, 15 | "file_url": "https://canvas.example.com/accounts/1/files/0/download", 16 | "attachment": null 17 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/assignment/AssignmentGroup.json: -------------------------------------------------------------------------------- 1 | { 2 | "id":123, 3 | "name":"Assignments", 4 | "position":1, 5 | "group_weight":50.0, 6 | "sis_source_id":null, 7 | "integration_data":{}, 8 | "rules":{} 9 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/assignment/AssignmentGroupList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id":123, 4 | "name":"Assignments", 5 | "position":1, 6 | "group_weight":50.0, 7 | "sis_source_id":null, 8 | "integration_data":{}, 9 | "rules":{} 10 | }, 11 | { 12 | "id":456, 13 | "name":"Exams", 14 | "position":2, 15 | "group_weight":50.0, 16 | "sis_source_id":null, 17 | "integration_data":{}, 18 | "rules":{} 19 | }, 20 | { 21 | "id":789, 22 | "name":"Imported Assignments", 23 | "position":3, 24 | "group_weight":0.0, 25 | "sis_source_id":null, 26 | "integration_data":{}, 27 | "rules":{} 28 | } 29 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/assignment/AssignmentOverride.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 4, 3 | "assignment_id": 80, 4 | "title": "Sec3", 5 | "due_at": null, 6 | "all_day": false, 7 | "all_day_date": null, 8 | "unlock_at": null, 9 | "lock_at": null, 10 | "course_section_id": 38 11 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/assignment/AssignmentOverrideList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 4, 4 | "assignment_id": 80, 5 | "title": "Sec1", 6 | "due_at": null, 7 | "all_day": false, 8 | "all_day_date": null, 9 | "unlock_at": null, 10 | "lock_at": null, 11 | "course_section_id": 38 12 | }, 13 | { 14 | "id": 5, 15 | "assignment_id": 81, 16 | "title": "Sec2", 17 | "due_at": null, 18 | "all_day": false, 19 | "all_day_date": null, 20 | "unlock_at": null, 21 | "lock_at": null, 22 | "course_section_id": 39 23 | }, 24 | { 25 | "id": 6, 26 | "assignment_id": 82, 27 | "title": "Sec3", 28 | "due_at": null, 29 | "all_day": false, 30 | "all_day_date": null, 31 | "unlock_at": null, 32 | "lock_at": null, 33 | "course_section_id": 40 34 | } 35 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/assignment/MinimalAssignment.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "description": "", 4 | "due_at": null, 5 | "unlock_at": null, 6 | "lock_at": null, 7 | "points_possible": 30, 8 | "grading_type": "points", 9 | "assignment_group_id": 1967, 10 | "grading_standard_id": null, 11 | "created_at": "2016-10-28T19:37:50Z", 12 | "updated_at": "2016-10-28T19:37:50Z", 13 | "peer_reviews": false, 14 | "automatic_peer_reviews": false, 15 | "position": 1, 16 | "grade_group_students_individually": false, 17 | "anonymous_peer_reviews": false, 18 | "group_category_id": null, 19 | "post_to_sis": false, 20 | "moderated_grading": false, 21 | "omit_from_final_grade": false, 22 | "course_id": 1146, 23 | "name": "Assignment1", 24 | "submission_types": [ 25 | "none" 26 | ], 27 | "has_submitted_submissions": false, 28 | "muted": false, 29 | "html_url": "https://canvas.example.edu/courses/1146/assignments/316000", 30 | "has_overrides": false, 31 | "needs_grading_count": 0, 32 | "integration_id": null, 33 | "integration_data": {}, 34 | "published": false, 35 | "unpublishable": true, 36 | "only_visible_to_overrides": false, 37 | "locked_for_user": false, 38 | "submissions_download_url": "https://canvas.example.edu/courses/1146/assignments/316000/submissions?zip=1" 39 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/authenticationLog/AuthenticationLogForAccount.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": { 3 | "events.login": null, 4 | "events.account": "https://fakeurl.instructure.com/api/v1/accounts/{events.account}", 5 | "events.user": null, 6 | "events.page_view": null 7 | }, 8 | "events": [{ 9 | "id": 154, 10 | "created_at": "2021-02-24T13:05:36Z", 11 | "event_type": "login", 12 | "links": { 13 | "login": 170, 14 | "account": 1, 15 | "user": 165, 16 | "page_view": null 17 | } 18 | }, { 19 | "id": 153, 20 | "created_at": "2021-02-24T13:04:47Z", 21 | "event_type": "logout", 22 | "links": { 23 | "login": 170, 24 | "account": 1, 25 | "user": 165, 26 | "page_view": null 27 | } 28 | }, { 29 | "id": 152, 30 | "created_at": "2021-02-24T13:02:02Z", 31 | "event_type": "login", 32 | "links": { 33 | "login": 170, 34 | "account": 1, 35 | "user": 165, 36 | "page_view": null 37 | } 38 | } 39 | ], 40 | "linked": { 41 | "logins": [], 42 | "accounts": [], 43 | "users": [], 44 | "page_views": [] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/authenticationLog/AuthenticationLogForLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": { 3 | "events.login": null, 4 | "events.account": "https://fakeurl.instructure.com/api/v1/accounts/{events.account}", 5 | "events.user": null, 6 | "events.page_view": null 7 | }, 8 | "events": [{ 9 | "id": 154, 10 | "created_at": "2021-02-24T13:05:36Z", 11 | "event_type": "login", 12 | "links": { 13 | "login": 170, 14 | "account": 1, 15 | "user": 165, 16 | "page_view": null 17 | } 18 | }, { 19 | "id": 153, 20 | "created_at": "2021-02-24T13:04:47Z", 21 | "event_type": "logout", 22 | "links": { 23 | "login": 170, 24 | "account": 1, 25 | "user": 165, 26 | "page_view": null 27 | } 28 | }, { 29 | "id": 152, 30 | "created_at": "2021-02-24T13:02:02Z", 31 | "event_type": "login", 32 | "links": { 33 | "login": 170, 34 | "account": 1, 35 | "user": 165, 36 | "page_view": null 37 | } 38 | } 39 | ], 40 | "linked": { 41 | "logins": [], 42 | "accounts": [], 43 | "users": [], 44 | "page_views": [] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/authenticationLog/AuthenticationLogForUser.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": { 3 | "events.login": null, 4 | "events.account": "https://fakeurl.instructure.com/api/v1/accounts/{events.account}", 5 | "events.user": null, 6 | "events.page_view": null 7 | }, 8 | "events": [{ 9 | "id": 154, 10 | "created_at": "2021-02-24T13:05:36Z", 11 | "event_type": "login", 12 | "links": { 13 | "login": 170, 14 | "account": 1, 15 | "user": 165, 16 | "page_view": null 17 | } 18 | }, { 19 | "id": 153, 20 | "created_at": "2021-02-24T13:04:47Z", 21 | "event_type": "logout", 22 | "links": { 23 | "login": 170, 24 | "account": 1, 25 | "user": 165, 26 | "page_view": null 27 | } 28 | }, { 29 | "id": 152, 30 | "created_at": "2021-02-24T13:02:02Z", 31 | "event_type": "login", 32 | "links": { 33 | "login": 170, 34 | "account": 1, 35 | "user": 165, 36 | "page_view": null 37 | } 38 | } 39 | ], 40 | "linked": { 41 | "logins": [], 42 | "accounts": [], 43 | "users": [], 44 | "page_views": [] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/CalendarEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 95, 3 | "title": "Testing", 4 | "location_name": "Somewhere", 5 | "location_address": "23 High Street, City, Code", 6 | "start_at": "2018-01-26T00:00:00Z", 7 | "end_at": "2018-01-26T00:00:00Z", 8 | "workflow_state": "active", 9 | "created_at": "2018-01-26T15:14:00Z", 10 | "updated_at": "2018-01-29T11:02:41Z", 11 | "all_day": true, 12 | "all_day_date": "2018-01-26", 13 | "comments": null, 14 | "type": "event", 15 | "description": "

Testing Description.

", 16 | "child_events_count": 0, 17 | "all_context_codes": "user_1", 18 | "context_code": "user_1", 19 | "parent_event_id": null, 20 | "hidden": false, 21 | "child_events": [], 22 | "url": "https://institution.instructure.com/api/v1/calendar_events/95", 23 | "html_url": "https://institution.instructure.com/calendar?event_id=95&include_contexts=user_1", 24 | "duplicates": [] 25 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/CalendarEvents.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 95, 4 | "title": "Testing", 5 | "location_name": "Somewhere", 6 | "location_address": "23 High Street, City, Code", 7 | "start_at": "2018-01-26T00:00:00Z", 8 | "end_at": "2018-01-26T00:00:00Z", 9 | "workflow_state": "active", 10 | "created_at": "2018-01-26T15:14:00Z", 11 | "updated_at": "2018-01-29T11:02:41Z", 12 | "all_day": true, 13 | "all_day_date": "2018-01-26", 14 | "comments": null, 15 | "type": "event", 16 | "description": "

Testing Description.

", 17 | "child_events_count": 0, 18 | "all_context_codes": "user_73", 19 | "context_code": "user_73", 20 | "parent_event_id": null, 21 | "hidden": false, 22 | "child_events": [], 23 | "url": "https://institution.instructure.com/api/v1/calendar_events/95", 24 | "html_url": "https://institution.instructure.com/calendar?event_id=95&include_contexts=user_73", 25 | "duplicates": [] 26 | } 27 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/CalendarNotFound.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "message": "The specified resource does not exist." 5 | } 6 | ], 7 | "error_report_id": 74797 8 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/CreateCalendarEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "title": "New Event", 4 | "location_name": "Somewhere", 5 | "location_address": "23 High Street, City, Code", 6 | "start_at": "2018-01-26T12:00:00Z", 7 | "end_at": "2018-01-26T13:00:00Z", 8 | "workflow_state": "active", 9 | "created_at": "2018-01-21T15:14:00Z", 10 | "updated_at": "2018-01-22T11:02:41Z", 11 | "all_day": false, 12 | "all_day_date": "2018-01-26", 13 | "comments": null, 14 | "type": "event", 15 | "description": "

Testing Description.

", 16 | "child_events_count": 0, 17 | "all_context_codes": "user_1", 18 | "context_code": "user_1", 19 | "parent_event_id": null, 20 | "hidden": false, 21 | "child_events": [], 22 | "url": "https://institution.instructure.com/api/v1/calendar_events/1", 23 | "html_url": "https://institution.instructure.com/calendar?event_id=1&include_contexts=user_1", 24 | "duplicates": [] 25 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/DeleteCalendarEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "title": "Delete Event", 4 | "location_name": "Somewhere", 5 | "location_address": "23 High Street, City, Code", 6 | "start_at": "2018-01-26T12:00:00Z", 7 | "end_at": "2018-01-26T13:00:00Z", 8 | "workflow_state": "active", 9 | "created_at": "2018-01-21T15:14:00Z", 10 | "updated_at": "2018-01-22T11:02:41Z", 11 | "all_day": false, 12 | "all_day_date": "2018-01-26", 13 | "comments": null, 14 | "type": "event", 15 | "description": "

Testing Description.

", 16 | "child_events_count": 0, 17 | "all_context_codes": "user_1", 18 | "context_code": "user_1", 19 | "parent_event_id": null, 20 | "hidden": false, 21 | "child_events": [], 22 | "url": "https://institution.instructure.com/api/v1/calendar_events/1", 23 | "html_url": "https://institution.instructure.com/calendar?event_id=1&include_contexts=user_1", 24 | "duplicates": [] 25 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/calendar/EditCalendarEvent.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "title": "Edit Event", 4 | "location_name": "Somewhere", 5 | "location_address": "23 High Street, City, Code", 6 | "start_at": "2018-01-26T12:00:00Z", 7 | "end_at": "2018-01-26T13:00:00Z", 8 | "workflow_state": "active", 9 | "created_at": "2018-01-21T15:14:00Z", 10 | "updated_at": "2018-01-22T11:02:41Z", 11 | "all_day": false, 12 | "all_day_date": "2018-01-26", 13 | "comments": null, 14 | "type": "event", 15 | "description": "

Testing Description.

", 16 | "child_events_count": 0, 17 | "all_context_codes": "user_1", 18 | "context_code": "user_1", 19 | "parent_event_id": null, 20 | "hidden": false, 21 | "child_events": [], 22 | "url": "https://institution.instructure.com/api/v1/calendar_events/1", 23 | "html_url": "https://institution.instructure.com/calendar?event_id=1&include_contexts=user_1", 24 | "duplicates": [] 25 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/communicationChannel/CommunicationChannelsList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1111, 4 | "address": "address@example.com", 5 | "type": "email", 6 | "workflow_state": "unconfirmed", 7 | "user_id": 123, 8 | "position": 1 9 | }, 10 | { 11 | "id": 1112, 12 | "address": "address@example.com", 13 | "type": "email", 14 | "workflow_state": "active", 15 | "user_id": 123, 16 | "position": 12 17 | } 18 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/communicationChannel/CreateCommunicationChannelResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1111, 3 | "address": "address@example.com", 4 | "type": "email", 5 | "workflow_state": "unconfirmed", 6 | "user_id": 123, 7 | "position": 1 8 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/communicationChannel/CreateCommunicationChannelSkipConfirmationResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1111, 3 | "address": "address@example.com", 4 | "type": "email", 5 | "workflow_state": "active", 6 | "user_id": 123, 7 | "position": 1 8 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/communicationChannel/DeleteCommunicationChannelResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1111, 3 | "address": "address@example.com", 4 | "type": "email", 5 | "workflow_state": null, 6 | "user_id": 123, 7 | "position": null 8 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/CreateContentMigrationRunning.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 44, 3 | "user_id": 899123456, 4 | "workflow_state": "running", 5 | "started_at": "2020-06-09T09:26:30Z", 6 | "finished_at": null, 7 | "migration_type": "course_copy_importer", 8 | "created_at": "2020-06-09T09:26:30Z", 9 | "migration_issues_url": "http://canvas.example.edu/api/v1/courses/20711/content_migrations/44/migration_issues", 10 | "migration_issues_count": 0, 11 | "settings": { 12 | "source_course_id": 20732, 13 | "source_course_name": "Destination course", 14 | "source_course_html_url": "http://canvas.example.edu/courses/20732" 15 | }, 16 | "progress_url": "http://canvas.example.edu/api/v1/progress/62", 17 | "migration_type_title": "Course copy" 18 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/CreateContentMigrationWaiting.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 45, 3 | "migration_type": "course_copy_importer", 4 | "migration_type_title": "Course copy", 5 | "migration_issues_url": "http://canvas.example.edu/api/v1/courses/20711/content_migrations/45/migration_issues", 6 | "migration_issues_count": 0, 7 | "progress_url": null, 8 | "user_id": 899123456, 9 | "workflow_state": "waiting_for_select", 10 | "created_at": "2020-06-09T09:22:51Z", 11 | "started_at": null, 12 | "finished_at": "2020-06-09T09:22:51Z" 13 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/CreateContentMigrationWithFile.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 47, 3 | "migration_type": "zip_file_importer", 4 | "migration_type_title": "File import", 5 | "migration_issues_url": "http://canvas.example.edu/api/v1/courses/20711/content_migrations/47/migration_issues", 6 | "migration_issues_count": 0, 7 | "progress_url": null, 8 | "user_id": 899123456, 9 | "workflow_state": "pre_processing", 10 | "created_at": "2020-06-09T09:22:51Z", 11 | "started_at": null, 12 | "finished_at": "2020-06-09T09:22:51Z", 13 | "pre_attachment": { 14 | "file_param": "file", 15 | "progress": null, 16 | "upload_url": "https://tempurl.net/files?token=token", 17 | "upload_params": { 18 | "filename": "nameOfFile", 19 | "content_type": null 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/CreateContentMigrationWithFile2.json: -------------------------------------------------------------------------------- 1 | { 2 | "location": "http://canvas.example.edu/api/v1/files/423", 3 | "instfs_uuid": "9893b0a4-6127-4f6b-ba26-41aa74794a71", 4 | "id": 423, 5 | "uuid": "xxxxxx", 6 | "folder_id": null, 7 | "display_name": "nameOfFile.zip", 8 | "filename": "nameOfFile.zip", 9 | "upload_status": "success", 10 | "content-type": "application/octet-stream", 11 | "url": "http://canvas.example.edu/files/423/download?download_frd=1&verifier=xxxxxx", 12 | "size": 9637, 13 | "created_at": "2020-06-08T11:58:53Z", 14 | "updated_at": "2020-06-08T11:58:53Z", 15 | "unlock_at": null, 16 | "locked": false, 17 | "hidden": false, 18 | "lock_at": null, 19 | "hidden_for_user": false, 20 | "thumbnail_url": null, 21 | "modified_at": "2020-06-08T11:58:53Z", 22 | "mime_class": "file", 23 | "media_entry_id": null, 24 | "locked_for_user": false 25 | } 26 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetContentMigrationCompleted.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 44, 3 | "user_id": 899123456, 4 | "workflow_state": "completed", 5 | "started_at": "2020-06-09T09:26:30-06:00", 6 | "finished_at": "2020-06-09T09:26:52-06:00", 7 | "migration_type": "course_copy_importer", 8 | "created_at": "2020-06-09T09:26:30-06:00", 9 | "migration_issues_url": "http://canvas.example.edu/api/v1/courses/20711/content_migrations/44/migration_issues", 10 | "migration_issues_count": 0, 11 | "settings": { 12 | "source_course_id": 20732, 13 | "source_course_name": "Destination course", 14 | "source_course_html_url": "http://canvas.example.edu/courses/20732" 15 | }, 16 | "progress_url": "http://canvas.example.edu/api/v1/progress/62", 17 | "migration_type_title": "Course copy" 18 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetContentMigrationCompletedWithIssues.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 46, 3 | "user_id": 899123456, 4 | "workflow_state": "completed", 5 | "started_at": "2020-06-09T09:26:30Z", 6 | "finished_at": "2020-06-09T09:26:52Z", 7 | "migration_type": "course_copy_importer", 8 | "created_at": "2020-06-09T09:26:30Z", 9 | "migration_issues_url": "domain/api/v1/courses/20713/content_migrations/46/migration_issues", 10 | "migration_issues_count": 1, 11 | "settings": { 12 | "source_course_id": 20732, 13 | "source_course_name": "Destination course", 14 | "source_course_html_url": "http://canvas.example.edu/courses/20732" 15 | }, 16 | "progress_url": "http://canvas.example.edu/api/v1/progress/64", 17 | "migration_type_title": "Course copy" 18 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetContentMigrationSelectiveCompleted.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 45, 3 | "user_id": 899123456, 4 | "workflow_state": "completed", 5 | "started_at": "2020-06-09T09:26:30Z", 6 | "finished_at": "2020-06-09T09:26:52Z", 7 | "migration_type": "course_copy_importer", 8 | "created_at": "2020-06-09T09:26:30Z", 9 | "migration_issues_url": "http://canvas.example.edu/api/v1/courses/20712/content_migrations/45/migration_issues", 10 | "migration_issues_count": 0, 11 | "settings": { 12 | "source_course_id": 20732, 13 | "source_course_name": "Destination course", 14 | "source_course_html_url": "http://canvas.example.edu/courses/20732" 15 | }, 16 | "progress_url": "http://canvas.example.edu/api/v1/progress/62", 17 | "migration_type_title": "Course copy" 18 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetMigrationIssue.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": 13, 3 | "description": "File required for content migration.", 4 | "workflow_state": "active", 5 | "fix_issue_html_url": null, 6 | "issue_type": "error", 7 | "created_at": "2020-06-04T12:11:14Z", 8 | "updated_at": "2020-06-04T12:11:14Z", 9 | "content_migration_url": "https://canvas.example.edu/api/v1/courses/20732/content_migrations/46" 10 | }] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetSelectiveData.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "course_settings", 4 | "property": "copy[all_course_settings]", 5 | "title": "Course settings" 6 | }, 7 | { 8 | "type": "syllabus_body", 9 | "property": "copy[all_syllabus_body]", 10 | "title": "Syllabus body" 11 | }, 12 | { 13 | "type": "assignments", 14 | "property": "copy[all_assignments]", 15 | "title": "Assignments", 16 | "count": 1, 17 | "sub_items_url": "http://canvas.example.edu/api/v1/courses/20712/content_migrations/45/selective_data?type=assignments" 18 | }, 19 | { 20 | "type": "discussion_topics", 21 | "property": "copy[all_discussion_topics]", 22 | "title": "Discussion topics", 23 | "count": 1, 24 | "sub_items_url": "http://canvas.example.edu/api/v1/courses/20712/content_migrations/45/selective_data?type=discussion_topics" 25 | }, 26 | { 27 | "type": "announcements", 28 | "property": "copy[all_announcements]", 29 | "title": "Announcements", 30 | "count": 1, 31 | "sub_items_url": "http://canvas.example.edu/api/v1/courses/20712/content_migrations/45/selective_data?type=announcements" 32 | }, 33 | { 34 | "type": "attachments", 35 | "property": "copy[all_attachments]", 36 | "title": "Files", 37 | "count": 1, 38 | "sub_items_url": "http://canvas.example.edu/api/v1/courses/20712/content_migrations/45/selective_data?type=attachments" 39 | } 40 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/contentMigration/GetSelectiveDataTypeAssignments.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "assignment_groups", 4 | "title": "Assignments", 5 | "migration_id": "g8778aa4b2607341370644e77445222b6", 6 | "property": "copy[assignment_groups][id_g8778aa4b2607341370644e77445222b6]", 7 | "sub_items": [ 8 | { 9 | "type": "assignments", 10 | "title": "assig1", 11 | "migration_id": "g3e2bd357bd4e3180a4ebb30301fe46fb", 12 | "property": "copy[assignments][id_g3e2bd357bd4e3180a4ebb30301fe46fb]" 13 | } 14 | ] 15 | } 16 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/CreateCourseDateError.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "conclude_at": [ 4 | { 5 | "attribute": "conclude_at", 6 | "type": "End date cannot be before start date", 7 | "message": "End date cannot be before start date" 8 | } 9 | ] 10 | } 11 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/CreateCourseSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 31517, 3 | "name": "SeleniumTestCourse", 4 | "account_id": 1, 5 | "start_at": null, 6 | "conclude_at": null, 7 | "grading_standard_id": null, 8 | "is_public": null, 9 | "allow_student_forum_attachments": false, 10 | "course_code": "SeleniumTestCourseCode", 11 | "default_view": "feed", 12 | "root_account_id": 1, 13 | "enrollment_term_id": 1, 14 | "open_enrollment": null, 15 | "allow_wiki_comments": null, 16 | "self_enrollment": null, 17 | "license": null, 18 | "restrict_enrollments_to_course_dates": false, 19 | "end_at": null, 20 | "public_syllabus": false, 21 | "storage_quota_mb": 5000, 22 | "is_public_to_auth_users": false, 23 | "hide_final_grades": false, 24 | "apply_assignment_group_weights": false, 25 | "calendar": { 26 | "ics": "https://canvas.example.edu/feeds/calendars/course_b22Ue3gLiAfl3D1B9YedUPP1BFsHe3ME6PXTuj2m.ics" 27 | }, 28 | "sis_course_id": null, 29 | "integration_id": null, 30 | "workflow_state": "unpublished" 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/DeleteConcludeCourseSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "conclude": true 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/DeleteCourseSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "delete": true 3 | } 4 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/GetCourseIncludeCourseImage.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1234, 3 | "name": "Test", 4 | "account_id": 567, 5 | "uuid": "p0LSApfM5qfLmxzV5PHsUWdIcfGHnw2Y3oIMNiMy", 6 | "start_at": null, 7 | "grading_standard_id": null, 8 | "is_public": false, 9 | "created_at": "2020-05-22T12:24:09Z", 10 | "course_code": "T-001", 11 | "default_view": "modules", 12 | "root_account_id": 1, 13 | "enrollment_term_id": 48, 14 | "license": "private", 15 | "grade_passback_setting": null, 16 | "end_at": null, 17 | "public_syllabus": false, 18 | "public_syllabus_to_auth": false, 19 | "storage_quota_mb": 5000, 20 | "is_public_to_auth_users": false, 21 | "hide_final_grades": false, 22 | "apply_assignment_group_weights": false, 23 | "calendar": { 24 | "ics": "https://instance.instructure.com/feeds/calendars/course_p0LSApfM5qfLmxzV5PHsUWdIcfGHnw2Y3oIMNjiMy.ics" 25 | }, 26 | "time_zone": "Europe/London", 27 | "image_download_url": "https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjc1NjI5fQ&utm_medium=referral&utm_source=canvas-prod&w=262&h=146&crop=faces%2Centropy&fit=crop&fm=jpg&cs=tinysrgb&q=80", 28 | "blueprint": false, 29 | "sis_course_id": null, 30 | "sis_import_id": null, 31 | "integration_id": "c89b1859-0da0-403c-a29f-db34f917459c", 32 | "enrollments": [], 33 | "workflow_state": "unpublished", 34 | "restrict_enrollments_to_course_dates": false 35 | } 36 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/course/UpdateCourseSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 705, 3 | "name": "UpdatedSeleniumTestName", 4 | "account_id": 63, 5 | "start_at": null, 6 | "grading_standard_id": null, 7 | "is_public": null, 8 | "course_code": "UpdatedSeleniumTestCourseCode", 9 | "default_view": "feed", 10 | "root_account_id": 1, 11 | "enrollment_term_id": 1, 12 | "end_at": null, 13 | "public_syllabus": false, 14 | "public_syllabus_to_auth": false, 15 | "storage_quota_mb": 5000, 16 | "is_public_to_auth_users": false, 17 | "hide_final_grades": false, 18 | "apply_assignment_group_weights": false, 19 | "calendar": { 20 | "ics": "https://sandbox.test.com/feeds/calendars/course_BW7Qv3BtXWpUX.ics" 21 | }, 22 | "time_zone": "America/Los_Angeles", 23 | "sis_course_id": "sis-id-1", 24 | "integration_id": null, 25 | "enrollments": [], 26 | "workflow_state": "unpublished", 27 | "restrict_enrollments_to_course_dates": false 28 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/file/GetFileSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 569, 3 | "uuid": "SUj23659sdfASF35h265kf352YTdnC4", 4 | "folder_id": 4207, 5 | "display_name": "file.txt", 6 | "filename": "file.txt", 7 | "content-type": "text/plain", 8 | "url": "http://www.example.com/files/569/download?download_frd=1&verifier=c6HdZmxOZa0Fiin2cbvZeI8I5ry7yqD7RChQzb6P", 9 | // file size in bytes 10 | "size": 43451, 11 | "created_at": "2012-07-06T14:58:50Z", 12 | "updated_at": "2012-07-06T14:58:50Z", 13 | "unlock_at": "2012-07-07T14:58:50Z", 14 | "locked": false, 15 | "hidden": false, 16 | "lock_at": "2012-07-20T14:58:50Z", 17 | "hidden_for_user": false, 18 | "thumbnail_url": null, 19 | "modified_at": "2012-07-06T14:58:50Z", 20 | // simplified content-type mapping 21 | "mime_class": "html", 22 | // identifier for file in third-party transcoding service 23 | "media_entry_id": "m-3z31gfpPf129dD3sSDF85SwSDFnwe", 24 | "locked_for_user": false, 25 | "lock_info": null, 26 | "lock_explanation": "This assignment is locked until September 1 at 12:00am", 27 | // optional: url to the document preview. This url is specific to the user 28 | // making the api call. Only included in submission endpoints. 29 | "preview_url": null 30 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/login/DeleteLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1235, 3 | "user_id": 1111, 4 | "account_id": 1, 5 | "unique_id": "testUpdated@email.com", 6 | "created_at": "2020-05-22T10:24:24Z", 7 | "sis_user_id": "testUpdated@email.com", 8 | "integration_id": "id", 9 | "authentication_provider_id": null 10 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/login/GetLoginForUser.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": 1234, 3 | "user_id": 1111, 4 | "account_id": 1, 5 | "unique_id": "test@email.com", 6 | "created_at": "2020-05-22T10:23:55Z", 7 | "sis_user_id": "test@email.com", 8 | "integration_id": null, 9 | "authentication_provider_id": 1, 10 | "authentication_provider_type": "canvas" 11 | }, { 12 | "id": 1235, 13 | "user_id": 1111, 14 | "account_id": 1, 15 | "unique_id": "test2@email.com", 16 | "created_at": "2020-05-22T10:24:24Z", 17 | "sis_user_id": null, 18 | "integration_id": "id", 19 | "authentication_provider_id": null 20 | }] 21 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/login/LoginUpdateFailedUniqueId.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "unique_id": [{ 4 | "attribute": "unique_id", 5 | "type": "taken", 6 | "message": "ID already in use for this account and authentication provider" 7 | } 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/login/UpdateLogin.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1235, 3 | "user_id": 1111, 4 | "account_id": 1, 5 | "unique_id": "testUpdated@email.com", 6 | "created_at": "2020-05-22T10:24:24Z", 7 | "sis_user_id": "testUpdated@email.com", 8 | "integration_id": "id", 9 | "authentication_provider_id": null 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/oauth/InvalidAccessTokenResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": [ 3 | { 4 | "message": "Invalid access token." 5 | } 6 | ] 7 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/oauth/InvalidClientIdResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": "invalid_client", 3 | "error_description": "unknown client" 4 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/oauth/InvalidRefreshTokenResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "error": "invalid_request", 3 | "error_description": "refresh_token not found" 4 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/oauth/SuccessfulAccessTokenResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "access_token": "1726~ACCESS_TOKEN_STRING", 3 | "token_type": "Bearer", 4 | "user": { 5 | "id": 1, 6 | "name": "John Smith" 7 | }, 8 | "expires_in": 3600 9 | } 10 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/oauth/UserUnauthorizedResponse.json: -------------------------------------------------------------------------------- 1 | { 2 | "status": "unauthorized", 3 | "errors": [ 4 | { 5 | "message": "user not authorized to perform that action" 6 | } 7 | ] 8 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/quiz/Quiz1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "title": "Quiz1", 4 | "html_url": "http://canvas.example.edu/courses/1/quizzes/2", 5 | "mobile_url": "http://canvas.example.edu/courses/1/quizzes/2?persist_healdess=1&force_user=1", 6 | "preview_url": "http://canvas.example.edu/courses/1/quizzes/2/take?preview=1", 7 | "description": "description1", 8 | "quiz_type": "assignment", 9 | "assignment_group_id": 3, 10 | "time_limit": 5, 11 | "shuffle_answers": "false", 12 | "hide_results": "always", 13 | "show_correct_answers": "true", 14 | "show_correct_answers_last_attempt": "true", 15 | "show_correct_answers_at": "2013-01-23T23:59:00-07:00", 16 | "hide_correct_answers_at": "2013-01-23T23:59:00-07:00", 17 | "one_time_results": "true", 18 | "scoring_policy": "keep_highest", 19 | "allowed_attempts": 3, 20 | "one_question_at_a_time": "false", 21 | "question_count": 12, 22 | "points_possible": 20, 23 | "cant_go_back": "false", 24 | "access_code": "2beornot2be", 25 | "ip_filter": "123.123.123.123", 26 | "due_at": "2013-01-23T23:59:00-07:00", 27 | "lock_at": "", 28 | "unlock_at": "2013-01-21T23:59:00-07:00", 29 | "published": "true", 30 | "unpublishable": "true", 31 | "locked_for_user": "false", 32 | "lock_explanation": "This quiz is locked until September 1 at 12:00am", 33 | "speedgrader_url": "http://canvas.example.edu/courses/1/speed_grader?assignment_id=1", 34 | "quiz_extensions_url": "http://canvas.example.edu/courses/1/quizzes/2/quiz_extensions", 35 | "permissions": {}, 36 | "all_dates": [], 37 | "version_number": 3, 38 | "question_types": [ 39 | "mutliple_choice", 40 | "essay" 41 | ] 42 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/quiz/Quiz2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 2, 3 | "title": "Quiz2", 4 | "html_url": "http://canvas.example.edu/courses/1/quizzes/2", 5 | "mobile_url": "http://canvas.example.edu/courses/1/quizzes/2?persist_healdess=1&force_user=1", 6 | "preview_url": "http://canvas.example.edu/courses/1/quizzes/2/take?preview=1", 7 | "description": "description2", 8 | "quiz_type": "assignment", 9 | "assignment_group_id": 2, 10 | "time_limit": 6, 11 | "shuffle_answers": "false", 12 | "hide_results": "always", 13 | "show_correct_answers": "true", 14 | "show_correct_answers_last_attempt": "true", 15 | "show_correct_answers_at": "2013-01-23T23:59:00-07:00", 16 | "hide_correct_answers_at": "2013-01-23T23:59:00-07:00", 17 | "one_time_results": "true", 18 | "scoring_policy": "keep_highest", 19 | "allowed_attempts": 2, 20 | "one_question_at_a_time": "false", 21 | "question_count": 15, 22 | "points_possible": 25, 23 | "cant_go_back": "false", 24 | "access_code": "2beornot2be", 25 | "ip_filter": "123.123.123.123", 26 | "due_at": "2013-01-23T23:59:00-07:00", 27 | "lock_at": "", 28 | "unlock_at": "2013-01-21T23:59:00-07:00", 29 | "published": "true", 30 | "unpublishable": "true", 31 | "locked_for_user": "false", 32 | "lock_info": null, 33 | "lock_explanation": "This quiz is locked until September 1 at 12:00am", 34 | "speedgrader_url": "http://canvas.instructure.com/courses/1/speed_grader?assignment_id=1", 35 | "quiz_extensions_url": "http://canvas.instructure.com/courses/1/quizzes/2/quiz_extensions", 36 | "permissions": {}, 37 | "all_dates": [], 38 | "version_number": 3, 39 | "question_types": [ 40 | "mutliple_choice", 41 | "essay" 42 | ] 43 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/quiz/QuizQuestionList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "quiz_id": 2, 5 | "position": 1, 6 | "question_name": "Quiz Question 1", 7 | "question_type": "multiple_choice_question", 8 | "question_text": "Is this quiz question number 1?", 9 | "points_possible": 5, 10 | "correct_comments": "That's correct!", 11 | "incorrect_comments": "Unfortunately, this IS quiz question number 1.", 12 | "neutral_comments": "This is a neutral comment for quiz question number 1", 13 | "answers": [] 14 | }, 15 | { 16 | "id": 2, 17 | "quiz_id": 2, 18 | "position": 2, 19 | "question_name": "Quiz Question 2", 20 | "question_type": "multiple_choice_question", 21 | "question_text": "Is this quiz question number 2?", 22 | "points_possible": 5, 23 | "correct_comments": "That's correct!", 24 | "incorrect_comments": "Unfortunately, this IS quiz question number 2.", 25 | "neutral_comments": "This is a neutral comment for quiz question number 2", 26 | "answers": [] 27 | } 28 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/quiz/QuizSubmissions.json: -------------------------------------------------------------------------------- 1 | { 2 | "quiz_submissions": [ 3 | { 4 | "id": 1, 5 | "quiz_id": 2, 6 | "user_id": 3, 7 | "submission_id": 1, 8 | "started_at": "2013-11-07T13:16:18Z", 9 | "finished_at": "2013-11-07T13:16:18Z", 10 | "end_at": "2013-11-07T13:16:18Z", 11 | "attempt": 3, 12 | "extra_attempts": 1, 13 | "extra_time": 60, 14 | "manually_unlocked": "true", 15 | "time_spent": 300, 16 | "score": 3, 17 | "score_before_regrade": 2, 18 | "kept_score": 5, 19 | "fudge_points": 1, 20 | "has_seen_results": "true", 21 | "workflow_state": "untaken", 22 | "overdue_and_needs_submission": "false" 23 | }, 24 | { 25 | "id": 2, 26 | "quiz_id": 2, 27 | "user_id": 3, 28 | "submission_id": 1, 29 | "started_at": "2013-11-07T13:16:18Z", 30 | "finished_at": "2013-11-07T13:16:18Z", 31 | "end_at": "2013-11-07T13:16:18Z", 32 | "attempt": 3, 33 | "extra_attempts": 1, 34 | "extra_time": 60, 35 | "manually_unlocked": "true", 36 | "time_spent": 300, 37 | "score": 3, 38 | "score_before_regrade": 2, 39 | "kept_score": 5, 40 | "fudge_points": 1, 41 | "has_seen_results": "true", 42 | "workflow_state": "untaken", 43 | "overdue_and_needs_submission": "false" 44 | } 45 | ] 46 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/role/Role.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "role": "AccountAdmin", 5 | "label": "Account Admin", 6 | "base_role_type": "AccountMembership", 7 | "workflow_state": "built_in", 8 | "permissions": { 9 | "view_analytics": { 10 | "enabled": true, 11 | "locked": false, 12 | "readonly": false, 13 | "explicit": false, 14 | "applies_to_descendants": true, 15 | "applies_to_self": true 16 | }, 17 | "manage_webhooks": { 18 | "enabled": true, 19 | "locked": false, 20 | "readonly": false, 21 | "explicit": false, 22 | "applies_to_descendants": true, 23 | "applies_to_self": true 24 | }, 25 | "manage_wiki": { 26 | "enabled": true, 27 | "locked": false, 28 | "readonly": false, 29 | "explicit": false, 30 | "applies_to_descendants": true, 31 | "applies_to_self": true 32 | }, 33 | "read_forum": { 34 | "enabled": true, 35 | "locked": false, 36 | "readonly": false, 37 | "explicit": false, 38 | "applies_to_descendants": true, 39 | "applies_to_self": true 40 | } 41 | } 42 | } 43 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/sampleErrorMessageWithErrorArray.json: -------------------------------------------------------------------------------- 1 | {"status":"bad_request","message":"Sample error message","error_report_id":1234, "errors":[{"message":"sample error message 1"}, {"message":"sample error message 2"}]} -------------------------------------------------------------------------------- /src/test/resources/SampleJson/sampleErrorMessageWithoutErrorArray.json: -------------------------------------------------------------------------------- 1 | {"status":"bad_request","message":"Sample error message","error_report_id":1234} -------------------------------------------------------------------------------- /src/test/resources/SampleJson/section/CreateSectionsSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 410, 3 | "course_id": 503, 4 | "name": "someName", 5 | "start_at": null, 6 | "end_at": null, 7 | "nonxlist_course_id": null, 8 | "sis_section_id": null, 9 | "sis_course_id": null, 10 | "integration_id": null, 11 | "sis_import_id": null 12 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/tab/UpdateTabSuccess.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "files", 3 | "html_url": "/courses/1234/files", 4 | "full_url": "https://cuboulder.test.instructure.com/courses/1234/files", 5 | "position": 8, 6 | "hidden": true, 7 | "visibility": "admins", 8 | "label": "Files", 9 | "type": "internal" 10 | } 11 | -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/IndividualUserList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "integration_id": null, 4 | "login_id": "testuser47login", 5 | "sis_import_id": null, 6 | "sortable_name": "User47, Test", 7 | "name": "Test User47", 8 | "short_name": "Test User47", 9 | "sis_user_id": 123497, 10 | "id": 47 11 | } 12 | ] -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/User1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "Student Number 1", 4 | "sortable_name": "Student, One", 5 | "short_name": "StOne", 6 | "sis_user_id": "Stu001", 7 | "sis_import_id": 18, 8 | "login_id": "student_01@numbers.example.com", 9 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a591868?s=80&r=g", 10 | "enrollments": [], 11 | "email": "student_01@numbers.example.com", 12 | "locale": "tlh", 13 | "last_login": "2012-05-30T17:45:25Z", 14 | "time_zone": "America/Denver", 15 | "bio": "I am the first" 16 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/User2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 2, 3 | "name": "Student Number 2", 4 | "sortable_name": "Student, Two", 5 | "short_name": "StTwo", 6 | "sis_user_id": "Stu002", 7 | "sis_import_id": 19, 8 | "login_id": "student_02@numbers.example.com", 9 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a592868?s=80&r=g", 10 | "enrollments": [], 11 | "email": "student_02@numbers.example.com", 12 | "locale": "tlh", 13 | "last_login": "2012-05-30T17:45:25Z", 14 | "time_zone": "America/Denver", 15 | "bio": "I am the second" 16 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserById.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 20, 3 | "name": "Student Number 20", 4 | "sortable_name": "Student, One", 5 | "short_name": "StOne", 6 | "sis_user_id": "Stu001", 7 | "sis_import_id": 18, 8 | "login_id": "student_01@numbers.example.com", 9 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a591868?s=80&r=g", 10 | "enrollments": [], 11 | "email": "student_01@numbers.example.com", 12 | "locale": "tlh", 13 | "last_login": "2012-05-30T17:45:25Z", 14 | "time_zone": "America/Denver", 15 | "bio": "I am the first", 16 | "created_at": "2011-05-30T17:45:25+01:00" 17 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserByIdLong.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 123450000000000020, 3 | "name": "Student Number 20 in instance 12345", 4 | "sortable_name": "Student, One", 5 | "short_name": "StOne", 6 | "sis_user_id": "Stu001", 7 | "sis_import_id": 18, 8 | "login_id": "student_01@numbers.example.com", 9 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a591868?s=80&r=g", 10 | "enrollments": [], 11 | "email": "student_01@numbers.example.com", 12 | "locale": "tlh", 13 | "last_login": "2012-05-30T17:45:25Z", 14 | "time_zone": "America/Denver", 15 | "bio": "I am the first" 16 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserBySelfIdentifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 32, 3 | "name": "Student 32", 4 | "sortable_name": "Student ThirtyOne", 5 | "short_name": "Student ThirtyOne", 6 | "login_id": "student@test.example.com", 7 | "avatar_url": "https://en.gravatar.com/avatar/12321asdfd", 8 | "locale": null, 9 | "permissions": { 10 | "can_update_name": false, 11 | "can_update_avatar": true 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserBySisIntegrationId.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 33, 3 | "name": "Student 33", 4 | "sortable_name": "Student ThirtyOne", 5 | "short_name": "Student ThirtyOne", 6 | "login_id": "student@test.example.com", 7 | "avatar_url": "https://en.gravatar.com/avatar/12321asdfd", 8 | "locale": null, 9 | "permissions": { 10 | "can_update_name": false, 11 | "can_update_avatar": true 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserBySisUserId.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 31, 3 | "name": "Student 31", 4 | "sortable_name": "Student ThirtyOne", 5 | "short_name": "Student ThirtyOne", 6 | "login_id": "student@test.example.com", 7 | "avatar_url": "https://en.gravatar.com/avatar/12321asdfd", 8 | "locale": null, 9 | "permissions": { 10 | "can_update_name": false, 11 | "can_update_avatar": true 12 | } 13 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserCreateFailedDuplicateId.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "user": { 4 | "pseudonyms": [ 5 | { 6 | "attribute": "pseudonyms", 7 | "type": "invalid", 8 | "message": "invalid" 9 | } 10 | ] 11 | }, 12 | "pseudonym": { 13 | "unique_id": [ 14 | { 15 | "attribute": "unique_id", 16 | "type": "taken", 17 | "message": "ID already in use for this account and authentication provider" 18 | } 19 | ] 20 | }, 21 | "observee": {}, 22 | "pairing_code": {} 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserCreateFailedIntegrationId.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "user": { 4 | "pseudonyms": [ 5 | { 6 | "attribute": "pseudonyms", 7 | "type": "invalid", 8 | "message": "invalid" 9 | } 10 | ] 11 | }, 12 | "pseudonym": { 13 | "integration_id": [ 14 | { 15 | "attribute": "integration_id", 16 | "type": "taken", 17 | "message": "Integration ID already in use" 18 | } 19 | ] 20 | }, 21 | "observee": {}, 22 | "pairing_code": {} 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserCreateFailedSisId.json: -------------------------------------------------------------------------------- 1 | { 2 | "errors": { 3 | "user": { 4 | "pseudonyms": [ 5 | { 6 | "attribute": "pseudonyms", 7 | "type": "invalid", 8 | "message": "invalid" 9 | } 10 | ] 11 | }, 12 | "pseudonym": { 13 | "sis_user_id": [ 14 | { 15 | "attribute": "sis_user_id", 16 | "type": "taken", 17 | "message": "SIS ID \"fakeemail@email.com\" is already in use" 18 | } 19 | ] 20 | }, 21 | "observee": {}, 22 | "pairing_code": {} 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/SampleJson/user/UserList.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "Student Number 1", 5 | "sortable_name": "Student, One", 6 | "short_name": "StOne", 7 | "sis_user_id": "Stu001", 8 | "sis_import_id": 18, 9 | "login_id": "student_01@numbers.example.com", 10 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a591868?s=80&r=g", 11 | "enrollments": [], 12 | "email": "student_01@numbers.example.com", 13 | "locale": "tlh", 14 | "last_login": "2012-05-30T17:45:25Z", 15 | "time_zone": "America/Denver", 16 | "bio": "I am the first" 17 | }, 18 | { 19 | "id": 2, 20 | "name": "Student Number 2", 21 | "sortable_name": "Student, Two", 22 | "short_name": "StTwo", 23 | "sis_user_id": "Stu002", 24 | "sis_import_id": 19, 25 | "login_id": "student_02@numbers.example.com", 26 | "avatar_url": "https://en.gravatar.com/avatar/d8cb8c8cd40ddf0cd05241443a592868?s=80&r=g", 27 | "enrollments": [], 28 | "email": "student_02@numbers.example.com", 29 | "locale": "tlh", 30 | "last_login": "2012-05-30T17:45:25Z", 31 | "time_zone": "America/Denver", 32 | "bio": "I am the second" 33 | } 34 | ] -------------------------------------------------------------------------------- /src/test/resources/TestModels/TestModel.json: -------------------------------------------------------------------------------- 1 | { 2 | "field1": "field1", 3 | "field2": "field2" 4 | } -------------------------------------------------------------------------------- /src/test/resources/TestModels/TestModels1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "field1": "object1Field1", 4 | "field2": "object1Field2" 5 | }, 6 | 7 | { 8 | "field1": "object2Field1", 9 | "field2": "object2Field2" 10 | } 11 | ] -------------------------------------------------------------------------------- /src/test/resources/TestModels/TestModels2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "field1": "object3Field1", 4 | "field2": "object3Field2" 5 | }, 6 | 7 | { 8 | "field1": "object4Field1", 9 | "field2": "object4Field2" 10 | } 11 | ] -------------------------------------------------------------------------------- /src/test/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Root logger option 2 | log4j.rootLogger=DEBUG, stdout 3 | 4 | # Direct log messages to stdout 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%-5p [%-45c] %m%n --------------------------------------------------------------------------------