canvas-workflow 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +27 -0
- data/LICENSE +21 -0
- data/README.md +69 -0
- data/_includes/newline +4 -0
- data/_layouts/assignment.html +20 -0
- data/_layouts/page.html +23 -0
- data/_layouts/syllabus.html +6 -0
- data/assets/_config.yml +41 -0
- data/bin/canvas +5 -0
- data/lib/canvas-workflow.rb +6 -0
- data/lib/canvas/workflow.rb +78 -0
- data/lib/canvas/workflow/cli.rb +24 -0
- data/lib/canvas/workflow/cli/deploy.rb +79 -0
- data/lib/canvas/workflow/cli/jekyll.rb +28 -0
- data/lib/canvas/workflow/cli/push.rb +55 -0
- data/lib/canvas/workflow/client.rb +13 -0
- data/lib/canvas/workflow/pandarus.rb +88 -0
- data/lib/canvas/workflow/tags.rb +10 -0
- data/lib/canvas/workflow/tags/assignment.rb +28 -0
- data/lib/canvas/workflow/tags/file.rb +35 -0
- data/lib/canvas/workflow/tags/gist.rb +20 -0
- data/lib/canvas/workflow/tags/icon.rb +20 -0
- data/lib/canvas/workflow/travis.rb +112 -0
- data/lib/canvas/workflow/version.rb +7 -0
- data/spec/assignment_spec.rb +63 -0
- data/spec/file_spec.rb +108 -0
- data/spec/fixtures/assignment.json +191 -0
- data/spec/fixtures/doesnotexist.json +1 -0
- data/spec/fixtures/file.json +28 -0
- data/spec/fixtures/nested.json +68 -0
- data/spec/fixtures/root.json +24 -0
- data/spec/gist_spec.rb +29 -0
- data/spec/icon_spec.rb +29 -0
- data/spec/spec_helper.rb +51 -0
- metadata +177 -0
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
# [ ] test with incorrect authorization [error]
|
4
|
+
# [ ] with non-existing prefix [error]
|
5
|
+
# [X] with non-existing course [error]
|
6
|
+
# [X] for non-existing path [error]
|
7
|
+
# [X] for non-existing file [error]
|
8
|
+
# [ ] for ambiguous file [error]
|
9
|
+
# [X] for existing file in root folder [pass]
|
10
|
+
# [X] for existing file in nested folder [pass]
|
11
|
+
|
12
|
+
describe Canvas::Workflow::Tags::FileTag do
|
13
|
+
let(:doc) { doc_with_content(content) }
|
14
|
+
let(:prefix) { doc.site.config['canvas']['prefix'] }
|
15
|
+
let(:course) { doc.site.config['canvas']['course'] }
|
16
|
+
let(:content) { "{% file #{path}#{file} %}" }
|
17
|
+
let(:output) do
|
18
|
+
doc.content = content
|
19
|
+
doc.output = Jekyll::Renderer.new(doc.site, doc).run
|
20
|
+
end
|
21
|
+
|
22
|
+
before :each do
|
23
|
+
stub_request(:get, url1).to_return(:status => status1, :body => fixture(fixture1), :headers => { "Content-Type" => "application/json; charset=utf-8" })
|
24
|
+
stub_request(:get, url2).to_return(:status => status2, :body => fixture(fixture2), :headers => { "Content-Type" => "application/json; charset=utf-8" })
|
25
|
+
end
|
26
|
+
let(:url1) { "#{prefix}/api/v1/courses/#{course}/folders/by_path/#{path}" }
|
27
|
+
let(:url2) { "#{prefix}/api/v1/folders/#{folder}/files?search_term=#{file}" }
|
28
|
+
|
29
|
+
context "with existing file" do
|
30
|
+
let(:status1) { 200 }
|
31
|
+
let(:status2) { 200 }
|
32
|
+
let(:fixture2) { "file" }
|
33
|
+
let(:file) { "file.txt" }
|
34
|
+
|
35
|
+
context "in course folder" do
|
36
|
+
let(:fixture1) { "root" }
|
37
|
+
let(:path) { "" }
|
38
|
+
let(:folder) { 2937 } # from id of :path in folders.json
|
39
|
+
|
40
|
+
it "produces the correct url" do
|
41
|
+
expect(output).to eq("<p>http://www.canvas.instructure.com/files/569/download?download_frd=1&verifier=c6HdZmxOZa0Fiin2cbvZeI8I5ry7yqD7RChQzb6P</p>\n")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "in nested folder" do
|
46
|
+
let(:fixture1) { "nested" }
|
47
|
+
let(:path) { "nested/examples/" }
|
48
|
+
let(:folder) { 2939 } # from id of :path in folders.json
|
49
|
+
|
50
|
+
it "produces the correct url" do
|
51
|
+
expect(output).to eq("<p>http://www.canvas.instructure.com/files/569/download?download_frd=1&verifier=c6HdZmxOZa0Fiin2cbvZeI8I5ry7yqD7RChQzb6P</p>\n")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with non-existing component" do
|
57
|
+
context "course does not exist" do
|
58
|
+
let(:output) do
|
59
|
+
doc.site.config['canvas']['course'] = course
|
60
|
+
doc.content = content
|
61
|
+
doc.output = Jekyll::Renderer.new(doc.site, doc).run
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:course) { "0123456789" }
|
65
|
+
let(:status1) { 404 }
|
66
|
+
let(:fixture1) { "doesnotexist" }
|
67
|
+
let(:path) { "nested/examples/" }
|
68
|
+
|
69
|
+
let(:status2) { "unused" }
|
70
|
+
let(:fixture2) { "doesnotexist" }
|
71
|
+
let(:folder) { "unused" }
|
72
|
+
let(:file) { "unused" }
|
73
|
+
|
74
|
+
it "raises an error" do
|
75
|
+
expect(-> { output }).to raise_error(Footrest::HttpError::NotFound)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "path does not exist" do
|
80
|
+
let(:status1) { 404 }
|
81
|
+
let(:fixture1) { "doesnotexist" }
|
82
|
+
let(:path) { "non-existent/path/" }
|
83
|
+
|
84
|
+
let(:status2) { "unused" }
|
85
|
+
let(:fixture2) { "doesnotexist" }
|
86
|
+
let(:folder) { "unused" }
|
87
|
+
let(:file) { "unused" }
|
88
|
+
|
89
|
+
it "raises an error" do
|
90
|
+
expect(-> { output }).to raise_error(Footrest::HttpError::NotFound)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "file does not exist on path" do
|
95
|
+
let(:status1) { 200 }
|
96
|
+
let(:status2) { 404 }
|
97
|
+
let(:fixture1) { "nested" }
|
98
|
+
let(:fixture2) { "doesnotexist" }
|
99
|
+
let(:path) { "nested/examples/" }
|
100
|
+
let(:folder) { 2939 } # from id of :path in folders.json
|
101
|
+
let(:file) { "non-existent-file.txt" }
|
102
|
+
|
103
|
+
it "raises an error" do
|
104
|
+
expect(-> { output }).to raise_error(Footrest::HttpError::NotFound)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,191 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
// the ID of the assignment
|
4
|
+
"id": 4,
|
5
|
+
// the name of the assignment
|
6
|
+
"name": "some assignment",
|
7
|
+
// the assignment description, in an HTML fragment
|
8
|
+
"description": "<p>Do the following:</p>...",
|
9
|
+
// The time at which this assignment was originally created
|
10
|
+
"created_at": "2012-07-01T23:59:00-06:00",
|
11
|
+
// The time at which this assignment was last modified in any way
|
12
|
+
"updated_at": "2012-07-01T23:59:00-06:00",
|
13
|
+
// the due date for the assignment. returns null if not present. NOTE: If this
|
14
|
+
// assignment has assignment overrides, this field will be the due date as it
|
15
|
+
// applies to the user requesting information from the API.
|
16
|
+
"due_at": "2012-07-01T23:59:00-06:00",
|
17
|
+
// the lock date (assignment is locked after this date). returns null if not
|
18
|
+
// present. NOTE: If this assignment has assignment overrides, this field will be
|
19
|
+
// the lock date as it applies to the user requesting information from the API.
|
20
|
+
"lock_at": "2012-07-01T23:59:00-06:00",
|
21
|
+
// the unlock date (assignment is unlocked after this date) returns null if not
|
22
|
+
// present NOTE: If this assignment has assignment overrides, this field will be
|
23
|
+
// the unlock date as it applies to the user requesting information from the API.
|
24
|
+
"unlock_at": "2012-07-01T23:59:00-06:00",
|
25
|
+
// whether this assignment has overrides
|
26
|
+
"has_overrides": true,
|
27
|
+
// (Optional) all dates associated with the assignment, if applicable
|
28
|
+
"all_dates": null,
|
29
|
+
// the ID of the course the assignment belongs to
|
30
|
+
"course_id": 123,
|
31
|
+
// the URL to the assignment's web page
|
32
|
+
"html_url": "https://...",
|
33
|
+
// the URL to download all submissions as a zip
|
34
|
+
"submissions_download_url": "https://example.com/courses/:course_id/assignments/:id/submissions?zip=1",
|
35
|
+
// the ID of the assignment's group
|
36
|
+
"assignment_group_id": 2,
|
37
|
+
// Boolean flag indicating whether the assignment requires a due date based on the
|
38
|
+
// account level setting
|
39
|
+
"due_date_required": true,
|
40
|
+
// Allowed file extensions, which take effect if submission_types includes
|
41
|
+
// 'online_upload'.
|
42
|
+
"allowed_extensions": ["docx", "ppt"],
|
43
|
+
// An integer indicating the maximum length an assignment's name may be
|
44
|
+
"max_name_length": 15,
|
45
|
+
// Boolean flag indicating whether or not Turnitin has been enabled for the
|
46
|
+
// assignment. NOTE: This flag will not appear unless your account has the Turnitin
|
47
|
+
// plugin available
|
48
|
+
"turnitin_enabled": true,
|
49
|
+
// Boolean flag indicating whether or not VeriCite has been enabled for the
|
50
|
+
// assignment. NOTE: This flag will not appear unless your account has the VeriCite
|
51
|
+
// plugin available
|
52
|
+
"vericite_enabled": true,
|
53
|
+
// Settings to pass along to turnitin to control what kinds of matches should be
|
54
|
+
// considered. originality_report_visibility can be 'immediate', 'after_grading',
|
55
|
+
// 'after_due_date', or 'never' exclude_small_matches_type can be null, 'percent',
|
56
|
+
// 'words' exclude_small_matches_value: - if type is null, this will be null also -
|
57
|
+
// if type is 'percent', this will be a number between 0 and 100 representing match
|
58
|
+
// size to exclude as a percentage of the document size. - if type is 'words', this
|
59
|
+
// will be number > 0 representing how many words a match must contain for it to be
|
60
|
+
// considered NOTE: This flag will not appear unless your account has the Turnitin
|
61
|
+
// plugin available
|
62
|
+
"turnitin_settings": null,
|
63
|
+
// If this is a group assignment, boolean flag indicating whether or not students
|
64
|
+
// will be graded individually.
|
65
|
+
"grade_group_students_individually": false,
|
66
|
+
// (Optional) assignment's settings for external tools if submission_types include
|
67
|
+
// 'external_tool'. Only url and new_tab are included (new_tab defaults to false).
|
68
|
+
// Use the 'External Tools' API if you need more information about an external
|
69
|
+
// tool.
|
70
|
+
"external_tool_tag_attributes": null,
|
71
|
+
// Boolean indicating if peer reviews are required for this assignment
|
72
|
+
"peer_reviews": false,
|
73
|
+
// Boolean indicating peer reviews are assigned automatically. If false, the
|
74
|
+
// teacher is expected to manually assign peer reviews.
|
75
|
+
"automatic_peer_reviews": false,
|
76
|
+
// Integer representing the amount of reviews each user is assigned. NOTE: This key
|
77
|
+
// is NOT present unless you have automatic_peer_reviews set to true.
|
78
|
+
"peer_review_count": 0,
|
79
|
+
// String representing a date the reviews are due by. Must be a date that occurs
|
80
|
+
// after the default due date. If blank, or date is not after the assignment's due
|
81
|
+
// date, the assignment's due date will be used. NOTE: This key is NOT present
|
82
|
+
// unless you have automatic_peer_reviews set to true.
|
83
|
+
"peer_reviews_assign_at": "2012-07-01T23:59:00-06:00",
|
84
|
+
// Boolean representing whether or not members from within the same group on a
|
85
|
+
// group assignment can be assigned to peer review their own group's work
|
86
|
+
"intra_group_peer_reviews": false,
|
87
|
+
// The ID of the assignment’s group set, if this is a group assignment. For group
|
88
|
+
// discussions, set group_category_id on the discussion topic, not the linked
|
89
|
+
// assignment.
|
90
|
+
"group_category_id": 1,
|
91
|
+
// if the requesting user has grading rights, the number of submissions that need
|
92
|
+
// grading.
|
93
|
+
"needs_grading_count": 17,
|
94
|
+
// if the requesting user has grading rights and the
|
95
|
+
// 'needs_grading_count_by_section' flag is specified, the number of submissions
|
96
|
+
// that need grading split out by section. NOTE: This key is NOT present unless you
|
97
|
+
// pass the 'needs_grading_count_by_section' argument as true. ANOTHER NOTE: it's
|
98
|
+
// possible to be enrolled in multiple sections, and if a student is setup that way
|
99
|
+
// they will show an assignment that needs grading in multiple sections
|
100
|
+
// (effectively the count will be duplicated between sections)
|
101
|
+
"needs_grading_count_by_section": [{"section_id":"123456","needs_grading_count":5}, {"section_id":"654321","needs_grading_count":0}],
|
102
|
+
// the sorting order of the assignment in the group
|
103
|
+
"position": 1,
|
104
|
+
// (optional, present if Sync Grades to SIS feature is enabled)
|
105
|
+
"post_to_sis": true,
|
106
|
+
// (optional, Third Party unique identifier for Assignment)
|
107
|
+
"integration_id": "12341234",
|
108
|
+
// (optional, Third Party integration data for assignment)
|
109
|
+
"integration_data": "12341234",
|
110
|
+
// whether the assignment is muted
|
111
|
+
"muted": null,
|
112
|
+
// the maximum points possible for the assignment
|
113
|
+
"points_possible": 12,
|
114
|
+
// the types of submissions allowed for this assignment list containing one or more
|
115
|
+
// of the following: 'discussion_topic', 'online_quiz', 'on_paper', 'none',
|
116
|
+
// 'external_tool', 'online_text_entry', 'online_url', 'online_upload'
|
117
|
+
// 'media_recording'
|
118
|
+
"submission_types": ["online_text_entry"],
|
119
|
+
// If true, the assignment has been submitted to by at least one student
|
120
|
+
"has_submitted_submissions": true,
|
121
|
+
// The type of grading the assignment receives; one of 'pass_fail', 'percent',
|
122
|
+
// 'letter_grade', 'gpa_scale', 'points'
|
123
|
+
"grading_type": "points",
|
124
|
+
// The id of the grading standard being applied to this assignment. Valid if
|
125
|
+
// grading_type is 'letter_grade' or 'gpa_scale'.
|
126
|
+
"grading_standard_id": null,
|
127
|
+
// Whether the assignment is published
|
128
|
+
"published": true,
|
129
|
+
// Whether the assignment's 'published' state can be changed to false. Will be
|
130
|
+
// false if there are student submissions for the assignment.
|
131
|
+
"unpublishable": false,
|
132
|
+
// Whether the assignment is only visible to overrides.
|
133
|
+
"only_visible_to_overrides": false,
|
134
|
+
// Whether or not this is locked for the user.
|
135
|
+
"locked_for_user": false,
|
136
|
+
// (Optional) Information for the user about the lock. Present when locked_for_user
|
137
|
+
// is true.
|
138
|
+
"lock_info": null,
|
139
|
+
// (Optional) An explanation of why this is locked for the user. Present when
|
140
|
+
// locked_for_user is true.
|
141
|
+
"lock_explanation": "This assignment is locked until September 1 at 12:00am",
|
142
|
+
// (Optional) id of the associated quiz (applies only when submission_types is
|
143
|
+
// ['online_quiz'])
|
144
|
+
"quiz_id": 620,
|
145
|
+
// (Optional) whether anonymous submissions are accepted (applies only to quiz
|
146
|
+
// assignments)
|
147
|
+
"anonymous_submissions": false,
|
148
|
+
// (Optional) the DiscussionTopic associated with the assignment, if applicable
|
149
|
+
"discussion_topic": null,
|
150
|
+
// (Optional) Boolean indicating if assignment will be frozen when it is copied.
|
151
|
+
// NOTE: This field will only be present if the AssignmentFreezer plugin is
|
152
|
+
// available for your account.
|
153
|
+
"freeze_on_copy": false,
|
154
|
+
// (Optional) Boolean indicating if assignment is frozen for the calling user.
|
155
|
+
// NOTE: This field will only be present if the AssignmentFreezer plugin is
|
156
|
+
// available for your account.
|
157
|
+
"frozen": false,
|
158
|
+
// (Optional) Array of frozen attributes for the assignment. Only account
|
159
|
+
// administrators currently have permission to change an attribute in this list.
|
160
|
+
// Will be empty if no attributes are frozen for this assignment. Possible frozen
|
161
|
+
// attributes are: title, description, lock_at, points_possible, grading_type,
|
162
|
+
// submission_types, assignment_group_id, allowed_extensions, group_category_id,
|
163
|
+
// notify_of_update, peer_reviews NOTE: This field will only be present if the
|
164
|
+
// AssignmentFreezer plugin is available for your account.
|
165
|
+
"frozen_attributes": ["title"],
|
166
|
+
// (Optional) If 'submission' is included in the 'include' parameter, includes a
|
167
|
+
// Submission object that represents the current user's (user who is requesting
|
168
|
+
// information from the api) current submission for the assignment. See the
|
169
|
+
// Submissions API for an example response. If the user does not have a submission,
|
170
|
+
// this key will be absent.
|
171
|
+
"submission": null,
|
172
|
+
// (Optional) If true, the rubric is directly tied to grading the assignment.
|
173
|
+
// Otherwise, it is only advisory. Included if there is an associated rubric.
|
174
|
+
"use_rubric_for_grading": true,
|
175
|
+
// (Optional) An object describing the basic attributes of the rubric, including
|
176
|
+
// the point total. Included if there is an associated rubric.
|
177
|
+
"rubric_settings": {"points_possible":12},
|
178
|
+
// (Optional) A list of scoring criteria and ratings for each rubric criterion.
|
179
|
+
// Included if there is an associated rubric.
|
180
|
+
"rubric": null,
|
181
|
+
// (Optional) If 'assignment_visibility' is included in the 'include' parameter,
|
182
|
+
// includes an array of student IDs who can see this assignment.
|
183
|
+
"assignment_visibility": [137, 381, 572],
|
184
|
+
// (Optional) If 'overrides' is included in the 'include' parameter, includes an
|
185
|
+
// array of assignment override objects.
|
186
|
+
"overrides": null,
|
187
|
+
// (Optional) If true, the assignment will be omitted from the student's final
|
188
|
+
// grade
|
189
|
+
"omit_from_final_grade": true
|
190
|
+
}
|
191
|
+
]
|
@@ -0,0 +1 @@
|
|
1
|
+
while(1);{"errors":[{"message":"The specified resource does not exist."}],"error_report_id":7039743803}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"size": 4,
|
4
|
+
"content-type": "text/plain",
|
5
|
+
"url": "http://www.canvas.instructure.com/files/569/download?download_frd=1&verifier=c6HdZmxOZa0Fiin2cbvZeI8I5ry7yqD7RChQzb6P",
|
6
|
+
"id": 569,
|
7
|
+
"display_name": "file.txt",
|
8
|
+
"created_at": "2012-07-06T14:58:50Z",
|
9
|
+
"updated_at": "2012-07-06T14:58:50Z",
|
10
|
+
"unlock_at": null,
|
11
|
+
"modified_at": "2012-07-06T14:58:50Z",
|
12
|
+
"locked": false,
|
13
|
+
"hidden": false,
|
14
|
+
"lock_at": null,
|
15
|
+
"locked_for_user": false,
|
16
|
+
"lock_info": null,
|
17
|
+
"lock_explanation": "This assignment is locked until September 1 at 12:00am",
|
18
|
+
"hidden_for_user": false,
|
19
|
+
"thumbnail_url": null,
|
20
|
+
// simplified content-type mapping
|
21
|
+
"mime_class": null,
|
22
|
+
// identifier for file in third-party transcoding service
|
23
|
+
"media_entry_id": null,
|
24
|
+
// optional: url to the document preview. This url is specific to the user
|
25
|
+
// making the api call. Only included in submission endpoints.
|
26
|
+
"preview_url": null
|
27
|
+
}
|
28
|
+
]
|
@@ -0,0 +1,68 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"context_type": "Course",
|
4
|
+
"context_id": 1401,
|
5
|
+
"files_count": 1,
|
6
|
+
"position": 3,
|
7
|
+
"updated_at": "2012-07-06T14:58:50Z",
|
8
|
+
"folders_url": "https://www.canvas.instructure.com/api/v1/folders/2937/folders",
|
9
|
+
"files_url": "https://www.canvas.instructure.com/api/v1/folders/2937/files",
|
10
|
+
"full_name": "course files",
|
11
|
+
"lock_at": "2012-07-06T14:58:50Z",
|
12
|
+
"id": 2937,
|
13
|
+
"folders_count": 1,
|
14
|
+
"name": "course files",
|
15
|
+
"parent_folder_id": null,
|
16
|
+
"created_at": "2012-07-06T14:58:50Z",
|
17
|
+
"unlock_at": null,
|
18
|
+
"hidden": false,
|
19
|
+
"hidden_for_user": false,
|
20
|
+
"locked": true,
|
21
|
+
"locked_for_user": false,
|
22
|
+
"for_submissions": false
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"context_type": "Course",
|
26
|
+
"context_id": 1401,
|
27
|
+
"files_count": 0,
|
28
|
+
"position": 3,
|
29
|
+
"updated_at": "2012-07-06T14:58:50Z",
|
30
|
+
"folders_url": "https://www.canvas.instructure.com/api/v1/folders/2938/folders",
|
31
|
+
"files_url": "https://www.canvas.instructure.com/api/v1/folders/2938/files",
|
32
|
+
"full_name": "course files/nested",
|
33
|
+
"lock_at": "2012-07-06T14:58:50Z",
|
34
|
+
"id": 2938,
|
35
|
+
"folders_count": 1,
|
36
|
+
"name": "nested",
|
37
|
+
"parent_folder_id": 2937,
|
38
|
+
"created_at": "2012-07-06T14:58:50Z",
|
39
|
+
"unlock_at": null,
|
40
|
+
"hidden": false,
|
41
|
+
"hidden_for_user": false,
|
42
|
+
"locked": true,
|
43
|
+
"locked_for_user": false,
|
44
|
+
"for_submissions": false
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"context_type": "Course",
|
48
|
+
"context_id": 1401,
|
49
|
+
"files_count": 1,
|
50
|
+
"position": 3,
|
51
|
+
"updated_at": "2012-07-06T14:58:50Z",
|
52
|
+
"folders_url": "https://www.canvas.instructure.com/api/v1/folders/2939/folders",
|
53
|
+
"files_url": "https://www.canvas.instructure.com/api/v1/folders/2939/files",
|
54
|
+
"full_name": "course files/nested/examples",
|
55
|
+
"lock_at": "2012-07-06T14:58:50Z",
|
56
|
+
"id": 2939,
|
57
|
+
"folders_count": 0,
|
58
|
+
"name": "examples",
|
59
|
+
"parent_folder_id": 2938,
|
60
|
+
"created_at": "2012-07-06T14:58:50Z",
|
61
|
+
"unlock_at": null,
|
62
|
+
"hidden": false,
|
63
|
+
"hidden_for_user": false,
|
64
|
+
"locked": true,
|
65
|
+
"locked_for_user": false,
|
66
|
+
"for_submissions": false
|
67
|
+
}
|
68
|
+
]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"context_type": "Course",
|
4
|
+
"context_id": 1401,
|
5
|
+
"files_count": 1,
|
6
|
+
"position": 3,
|
7
|
+
"updated_at": "2012-07-06T14:58:50Z",
|
8
|
+
"folders_url": "https://www.canvas.instructure.com/api/v1/folders/2937/folders",
|
9
|
+
"files_url": "https://www.canvas.instructure.com/api/v1/folders/2937/files",
|
10
|
+
"full_name": "course files",
|
11
|
+
"lock_at": "2012-07-06T14:58:50Z",
|
12
|
+
"id": 2937,
|
13
|
+
"folders_count": 1,
|
14
|
+
"name": "course files",
|
15
|
+
"parent_folder_id": null,
|
16
|
+
"created_at": "2012-07-06T14:58:50Z",
|
17
|
+
"unlock_at": null,
|
18
|
+
"hidden": false,
|
19
|
+
"hidden_for_user": false,
|
20
|
+
"locked": true,
|
21
|
+
"locked_for_user": false,
|
22
|
+
"for_submissions": false
|
23
|
+
}
|
24
|
+
]
|
data/spec/gist_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Canvas::Workflow::Tags::GistTag do
|
4
|
+
let(:doc) { doc_with_content(content) }
|
5
|
+
let(:content) { "{% gist #{gist} %}" }
|
6
|
+
let(:output) do
|
7
|
+
doc.content = content
|
8
|
+
doc.output = Jekyll::Renderer.new(doc.site, doc).run
|
9
|
+
end
|
10
|
+
let(:html) { "<p><iframe style=\"width: 100%; height: 400px;\" title=\"GitHub gist\" src=\"https://www.edu-apps.org/tools/github/github_summary_gist.html\##{gist}\" width=\"100%\" height=\"400\" allowfullscreen=\"allowfullscreen\" webkitallowfullscreen=\"webkitallowfullscreen\" mozallowfullscreen=\"mozallowfullscreen\"></iframe></p>\n" }
|
11
|
+
|
12
|
+
context "valid gist" do
|
13
|
+
let(:gist) { "jiverson002/a409d902fcea90800c9ea6c02c71d97d" }
|
14
|
+
|
15
|
+
it "produces the correct html" do
|
16
|
+
expect(output).to eq(html)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "invalid gist" do
|
21
|
+
context "no gist present" do
|
22
|
+
let(:gist) { "" }
|
23
|
+
|
24
|
+
it "raises an error" do
|
25
|
+
expect(-> { output }).to raise_error(ArgumentError, "Cannot have empty gist")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|