canvas-workflow 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|