d2l_sdk 0.1.10 → 0.1.11

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.
@@ -59,12 +59,14 @@ def get_user_demographics(user_id, field_ids = '', bookmark = '')
59
59
  path += "?"
60
60
  path += "fieldIds=#{field_ids}&" if field_ids != ''
61
61
  path += "bookmark=#{bookmark}" if bookmark != ''
62
+ _get(path)
62
63
  end
63
64
 
64
- def check_demographics_user_entry_data_validity(demographics_user_entry_data)
65
+ def check_demographics_entry_data_validity(demographics_entry_data)
65
66
  # A hash with one value, "EntryValues", which is an array of hashes that
66
67
  # include the keys "Name" and "Values", where "Name" is a string and "Values"
67
68
  # is an array of string.
69
+ # { "key" => [ { "key" => "string", "key" => [] } ] }
68
70
  schema = {
69
71
  'type' => 'object',
70
72
  'required' => %w(EntryValues),
@@ -94,14 +96,27 @@ def check_demographics_user_entry_data_validity(demographics_user_entry_data)
94
96
  }
95
97
  }
96
98
  }
97
- JSON::Validator.validate!(schema, demographics_user_entry_data, validate_schema: true)
99
+ JSON::Validator.validate!(schema, demographics_entry_data, validate_schema: true)
98
100
  end
99
101
 
100
102
 
101
- # TODO: Update the demographics entries for a single user.
103
+ # REVIEW: Update the demographics entries for a single user.
102
104
  # Return: a DemographicsUserEntryData JSON block containing the user’s updated entries.
103
105
  def update_user_demographics(user_id, demographics_entry_data)
106
+ payload =
107
+ {
108
+ "EntryValues" =>
109
+ [
110
+ {
111
+ "Name" => "placeholder_name",
112
+ "Values" => %w(value1 value2)
113
+ }
114
+ ]
115
+ }.merge!(demographics_entry_data)
104
116
  # PUT /d2l/api/lp/(version)/demographics/users/(userId)
117
+ path = "/d2l/api/lp/#{$lp_ver}/demographics/users/#{user_id}"
118
+ check_demographics_user_entry_data_validity(payload)
119
+ _put(path, payload)
105
120
  end
106
121
 
107
122
  ########################
@@ -117,7 +132,7 @@ end
117
132
  # Retrieve list of all demographics fields
118
133
  def get_all_demographic_fields(bookmark = '')
119
134
  path = "/d2l/api/lp/#{$lp_ver}/demographics/fields/"
120
- path += "#{bookmark}" if bookmark != ''
135
+ path += bookmark.to_s if bookmark != ''
121
136
  _get(path)
122
137
  # returns paged result set of DemographicsField JSON blocks
123
138
  end
@@ -154,7 +169,7 @@ def create_demographic_field(demographics_field)
154
169
  "Name" => "String",
155
170
  "Description" => "String",
156
171
  "DataTypeId" => "String:GUID"
157
- }
172
+ }.merge!(demographics_field)
158
173
  check_create_demographics_field(payload)
159
174
  _post(path, payload)
160
175
  # RETURNS: fetch form of a DemographicsField JSON block
@@ -168,7 +183,7 @@ def check_update_demographics_field(demographics_data)
168
183
  'required' => %w(Name Description),
169
184
  'properties' => {
170
185
  'Name' => { 'type' => 'string' },
171
- 'Description' => { 'type' => 'string' },
186
+ 'Description' => { 'type' => 'string' }
172
187
  }
173
188
  }
174
189
  JSON::Validator.validate!(schema, demographics_data, validate_schema: true)
@@ -184,7 +199,7 @@ def update_demographics_field(field_id, demographics_field)
184
199
  "Name" => "String",
185
200
  "Description" => "String",
186
201
  "DataTypeId" => "String:GUID"
187
- }
202
+ }.merge!(demographics_field)
188
203
  check_update_demographics_field(payload)
189
204
  _put(path, payload)
190
205
  # RETURNS: fetch form of a DemographicsField JSON block
@@ -198,7 +213,7 @@ end
198
213
  # uses DataTypeId's as a paging control value
199
214
  def get_all_demographic_types(bookmark = '')
200
215
  path = "/d2l/api/lp/#{$lp_ver}/demographics/dataTypes/"
201
- path += "#{bookmark}" if bookmark != ''
216
+ path += bookmark.to_s if bookmark != ''
202
217
  _get(path)
203
218
  # returns paged result set of DemographicsDataType JSON blocks
204
219
  end
@@ -6,29 +6,61 @@ require 'json-schema'
6
6
  ##################
7
7
 
8
8
  # REVIEW: Delete a particular discussion forum from an org unit.
9
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
10
- def dete_org_unit_discussion(org_unit_id, forum_id)
9
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
10
+ def delete_org_unit_discussion(org_unit_id, forum_id)
11
11
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}"
12
12
  _delete(path)
13
13
  end
14
14
 
15
15
  # REVIEW: Retrieve a list of all discussion forums for an org unit.
16
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/
16
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/
17
17
  def get_org_unit_discussions(org_unit_id)
18
18
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/"
19
19
  _get(path)
20
20
  end
21
21
 
22
22
  # REVIEW: Retrieve a particular discussion forum for an org unit.
23
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
23
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
24
24
  def get_org_unit_discussion(org_unit_id, forum_id)
25
25
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}"
26
26
  _get(path)
27
27
  end
28
28
 
29
- # TODO: Validate input of create_org_unit_discussion
30
- # Create a new forum for an org unit.
31
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/
29
+ def check_forum_data_validity(forum_data)
30
+ schema = {
31
+ 'type' => 'object',
32
+ 'required' => %w(Name Description ShowDescriptionInTopics StartDate
33
+ EndDate PostStartDate PostEndDate IsHidden
34
+ IsLocked RequiresApproval MustPostToParticipate
35
+ DisplayInCalendar DisplayPostDatesInCalendar),
36
+ 'properties' => {
37
+ 'Name' => { 'type' => 'string' },
38
+ 'Description' => {
39
+ 'type' => 'object',
40
+ 'properties' =>
41
+ {
42
+ "Text" => { 'type' => "string" },
43
+ "Html" => { 'type' => %w(string null) }
44
+ }
45
+ },
46
+ 'ShowDescriptionInTopics' => { 'type' => %w(boolean null) },
47
+ 'StartDate' => { 'type' => %w(string null) },
48
+ 'EndDate' => { 'type' => %w(string null) },
49
+ 'PostStartDate' => { 'type' => %w(string null) },
50
+ 'PostEndDate' => { 'type' => %w(string null) },
51
+ 'IsHidden' => { 'type' => 'boolean' },
52
+ 'IsLocked' => { 'type' => 'boolean' },
53
+ 'RequiresApproval' => { 'type' => 'boolean' }, #: <boolean>,
54
+ 'MustPostToParticipate' => { 'type' => %w(boolean null) },
55
+ 'DisplayInCalendar' => { 'type' => %w(boolean null) }, # Added with LE API v1.11
56
+ 'DisplayPostDatesInCalendar' => { 'type' => %w(boolean null) }
57
+ }
58
+ }
59
+ JSON::Validator.validate!(schema, forum_data, validate_schema: true)
60
+ end
61
+
62
+ # REVIEW: Create a new forum for an org unit.
63
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/
32
64
  def create_org_unit_discussion(org_unit_id, forum_data)
33
65
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/"
34
66
  payload =
@@ -36,10 +68,10 @@ def create_org_unit_discussion(org_unit_id, forum_data)
36
68
  'Name' => '', #: <string>,
37
69
  'Description' => #: { <composite:RichText> },
38
70
  {
39
- "Text" => "",#<string:plaintext_version_of_text>,
40
- "Html" => nil #<string:HTML_formatted_version_of_text>|null
71
+ "Text" => "", # <string:plaintext_version_of_text>,
72
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
41
73
  },
42
- 'ShowDescriptionInTopics' => nil, #: <boolean>|null, // Added with LE API v1.14
74
+ 'ShowDescriptionInTopics' => nil, # : <boolean>|null, // Added with LE API v1.14
43
75
  'StartDate' => nil, #: <string:UTCDateTime>|null,
44
76
  'EndDate' => nil, #: <string:UTCDateTime>|null,
45
77
  'PostStartDate' => nil, #: <string:UTCDateTime>|null,
@@ -52,75 +84,240 @@ def create_org_unit_discussion(org_unit_id, forum_data)
52
84
  'DisplayInCalendar' => nil, #: <boolean>|null, // Added with LE API v1.11
53
85
  'DisplayPostDatesInCalendar' => nil, #: <boolean>|null // Added with LE API v1.11
54
86
  }.merge!(forum_data)
55
- # TODO: Validate payload
87
+ # REVIEW: Validate payload
88
+ check_forum_data_validity(payload)
56
89
  _post(path, payload)
57
90
  end
58
91
 
59
- # TODO: Update a forum for an org unit.
60
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)
92
+ # REVIEW: Update a forum for an org unit.
93
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}
94
+ # NOTE: < LE v 1.10 ignores date filed of the forum_data
95
+ # NOTE: >= LE v 1.11 applies date fields that are sent, otherwise they're
96
+ # assumed null.
97
+ def update_forum(org_unit_id, forum_id, forum_data)
98
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/"
99
+ payload =
100
+ {
101
+ 'Name' => '', #: <string>,
102
+ 'Description' => #: { <composite:RichText> },
103
+ {
104
+ "Text" => "", # <string:plaintext_version_of_text>,
105
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
106
+ },
107
+ 'ShowDescriptionInTopics' => nil, #: <boolean>|null, // Added with LE API v1.14
108
+ 'StartDate' => nil, #: <string:UTCDateTime>|null,
109
+ 'EndDate' => nil, #: <string:UTCDateTime>|null,
110
+ 'PostStartDate' => nil, #: <string:UTCDateTime>|null,
111
+ 'PostEndDate' => nil, # <string:UTCDateTime>|null,
112
+ 'AllowAnonymous' => false, # <boolean>,
113
+ 'IsLocked' => false, #: <boolean>,
114
+ 'IsHidden' => false, #: <boolean>,
115
+ 'RequiresApproval' => '', #: <boolean>,
116
+ 'MustPostToParticipate' => nil, #: <boolean>|null,
117
+ 'DisplayInCalendar' => nil, #: <boolean>|null, // Added with LE API v1.11
118
+ 'DisplayPostDatesInCalendar' => nil, #: <boolean>|null // Added with LE API v1.11
119
+ }.merge!(forum_data)
120
+ # REVIEW: Validate payload
121
+ check_forum_data_validity(payload)
122
+ _put(path, payload)
123
+ # RETURNS: Forum JSON block
124
+ end
61
125
 
62
126
  ##################
63
127
  ## TOPICS: #######
64
128
  ##################
65
129
 
66
- # TODO: Delete a particular topic from the provided discussion forum in an org unit.
67
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
68
- # TODO: Delete a group restriction for a discussion forum topic.
69
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
130
+ # REVIEW: Delete a particular topic from the provided discussion forum in an org unit.
131
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
132
+ def delete_topic(org_unit_id, forum_id, topic_id)
133
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
134
+ _delete(path)
135
+ end
136
+
137
+ # REVIEW: Delete a group restriction for a discussion forum topic.
138
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
139
+ def delete_topic_group_restriction(org_unit_id, forum_id, topic_id)
140
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
141
+ _delete(path)
142
+ end
143
+
70
144
  # REVIEW: Retrieve topics from the provided discussion forum in an org unit.
71
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/
145
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/
72
146
  def get_forum_topics(org_unit_id, forum_id)
73
147
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/"
74
148
  _get(path)
75
149
  end
76
150
 
77
151
  # REVIEW: Retrieve a particular topic from the provided discussion forum in an org unit.
78
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
152
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
79
153
  def get_forum_topic(org_unit_id, forum_id, topic_id)
80
154
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
81
155
  _get(path)
82
156
  end
83
157
 
84
158
  # REVIEW: Retrieve the group restrictions for a discussion forum topic.
85
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
159
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
86
160
  def get_forum_topic_group_restrictions(org_unit_id, forum_id, topic_id)
87
161
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
88
162
  _get(path)
89
163
  end
90
164
 
91
- # TODO: Create a new topic for the provided discussion forum in an org unit.
92
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/
93
- # TODO: Update an existing topic for the provided discussion forum in an org unit.
94
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)
95
- # TODO: Add a group to the group restriction list for a discussion forum topic.
96
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/groupRestrictions/
165
+ def check_create_topic_data_validity(create_topic_data)
166
+ schema = {
167
+ 'type' => 'object',
168
+ 'required' => %w(Name Description AllowAnonymousPosts StartDate
169
+ EndDate UnlockStartDate UnlockEndDate IsHidden
170
+ IsLocked RequiresApproval ScoreOutOf IsAutoScore
171
+ IncludeNonScoredValues ScoringType MustPostToParticipate
172
+ RatingType DisplayInCalendar DisplayUnlockDatesInCalendar),
173
+ 'properties' =>
174
+ {
175
+ 'Name' => { 'type' => 'string' },
176
+ 'Description' =>
177
+ {
178
+ 'type' => 'object',
179
+ 'properties' =>
180
+ {
181
+ "Content" => { 'type' => "string" },
182
+ "Type" => { 'type' => "string" }
183
+ }
184
+ },
185
+ 'AllowAnonymousPosts' => { 'type' => 'boolean' },
186
+ 'StartDate' => { 'type' => %w(string null) },
187
+ 'EndDate' => { 'type' => %w(string null) },
188
+ 'UnlockStartDate' => { 'type' => %w(string null) },
189
+ 'UnlockEndDate' => { 'type' => %w(string null) },
190
+ 'IsHidden' => { 'type' => 'boolean' },
191
+ 'IsLocked' => { 'type' => 'boolean' },
192
+ 'RequiresApproval' => { 'type' => 'boolean' }, #: <boolean>,
193
+ 'ScoreOutOf' => { 'type' => %w(integer null) },
194
+ 'IsAutoScore' => { 'type' => 'boolean' }, # Added with LE API v1.11
195
+ 'IncludeNonScoredValues' => { 'type' => 'boolean' },
196
+ 'ScoringType' => { 'type' => %w(string null) },
197
+ 'MustPostToParticipate' => { 'type' => 'boolean' }, #: <boolean>,
198
+ 'RatingType' => { 'type' => %w(string null) },
199
+ 'DisplayInCalendar' => { 'type' => %w(boolean null) }, # Added with LE API v1.12
200
+ 'DisplayUnlockDatesInCalendar' => { 'type' => %w(boolean null) } # Added with LE API v1.12
201
+ }
202
+ }
203
+ JSON::Validator.validate!(schema, create_topic_data, validate_schema: true)
204
+ end
205
+
206
+ # REVIEW: Create a new topic for the provided discussion forum in an org unit.
207
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/
208
+ def create_forum_topic(org_unit_id, forum_id, create_topic_data)
209
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/"
210
+ payload =
211
+ {
212
+ "Name" => "", # : <string>,
213
+ "Description" =>
214
+ {
215
+ "Text" => "", # <string:plaintext_version_of_text>,
216
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
217
+ }, # { <composite:RichTextInput> },
218
+ "AllowAnonymousPosts" => false, # <boolean>,
219
+ "StartDate" => nil, # <string:UTCDateTime>|null,
220
+ "EndDate" => nil, # : <string:UTCDateTime>|null,
221
+ "IsHidden" => false, # : <boolean>,
222
+ "UnlockStartDate" => nil, # : <string:UTCDateTime>|null,
223
+ "UnlockEndDate" => nil, # : <string:UTCDateTime>|null,
224
+ "RequiresApproval" => false, # : <boolean>,
225
+ "ScoreOutOf" => nil, # : <number>|null,
226
+ "IsAutoScore" => false, # : <boolean>,
227
+ "IncludeNonScoredValues" => "", # : <boolean>,
228
+ "ScoringType" => nil, # : <string:SCORING_T>|null,
229
+ "IsLocked" => false, # : <boolean>,
230
+ "MustPostToParticipate" => false, # : <boolean>,
231
+ "RatingType" => nil, # : <string:RATING_T>|null,
232
+ "DisplayInCalendar" => nil, # : <boolean>|null, // Added with LE API v1.12
233
+ "DisplayUnlockDatesInCalendar" => nil, # : <boolean>|null // Added with LE API v1.12
234
+ }.merge!(create_topic_data)
235
+ check_create_topic_data_validity(payload) # REVIEW: Validity check of topic data
236
+ _post(path, payload)
237
+ # RETURNS: Topic JSON data block
238
+ end
239
+
240
+ # REVIEW: Update an existing topic for the provided discussion forum in an org unit.
241
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}
242
+ def update_forum_topic(org_unit_id, forum_id, topic_id, create_topic_data)
243
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}"
244
+ payload =
245
+ {
246
+ "Name" => "", # : <string>,
247
+ "Description" =>
248
+ {
249
+ "Text" => "", # <string:plaintext_version_of_text>,
250
+ "Html" => nil # <string:HTML_formatted_version_of_text>|null
251
+ }, # { <composite:RichTextInput> },
252
+ "AllowAnonymousPosts" => false, # <boolean>,
253
+ "StartDate" => nil, # <string:UTCDateTime>|null,
254
+ "EndDate" => nil, # : <string:UTCDateTime>|null,
255
+ "IsHidden" => false, # : <boolean>,
256
+ "UnlockStartDate" => nil, # : <string:UTCDateTime>|null,
257
+ "UnlockEndDate" => nil, # : <string:UTCDateTime>|null,
258
+ "RequiresApproval" => false, # : <boolean>,
259
+ "ScoreOutOf" => nil, # : <number>|null,
260
+ "IsAutoScore" => false, # : <boolean>,
261
+ "IncludeNonScoredValues" => "", # : <boolean>,
262
+ "ScoringType" => nil, # : <string:SCORING_T>|null,
263
+ "IsLocked" => false, # : <boolean>,
264
+ "MustPostToParticipate" => false, # : <boolean>,
265
+ "RatingType" => nil, # : <string:RATING_T>|null,
266
+ "DisplayInCalendar" => nil, # : <boolean>|null, // Added with LE API v1.12
267
+ "DisplayUnlockDatesInCalendar" => nil, # : <boolean>|null // Added with LE API v1.12
268
+ }.merge!(create_topic_data)
269
+ check_create_topic_data_validity(payload) # REVIEW: Validity check of topic data
270
+ _post(path, payload)
271
+ # RETURNS: Topic JSON data block
272
+ end
273
+
274
+ # REVIEW: Add a group to the group restriction list for a discussion forum topic.
275
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/
276
+ def add_group_to_group_restriction_list(org_unit_id, forum_id, topic_id, group_id)
277
+ raise ArgumentError, "Argument 'group_id' is not numeric value." unless group_id.is_a? Numeric
278
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/groupRestrictions/"
279
+ payload = { "GroupRestriction" => { "GroupId" => group_id } }
280
+ _put(path, payload)
281
+ # RETURNS: ??
282
+ end
97
283
 
98
284
  ##################
99
285
  ## POSTS: ########
100
286
  ##################
101
287
 
102
- # TODO: Delete a particular post from a discussion forum topic.
103
- # => DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
104
- # TODO: DELETE /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
288
+ # REVIEW: Delete a particular post from a discussion forum topic.
289
+ # => DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
290
+ def delete_topic_post(org_unit_id, forum_id, topic_id, post_id)
291
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
292
+ _delete(path)
293
+ end
294
+
295
+ # REVIEW: DELETE /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
105
296
  # => Delete the current user context’s rating for a particular post from a discussion forum topic.
297
+ def delete_current_user_context_post_rating
298
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
299
+ _delete(path)
300
+ # NOTE: Doing so is actually an update, setting the current user's rating
301
+ # of a post to null
302
+ end
106
303
 
107
304
  # REVIEW: Retrieve all posts in a discussion forum topic.
108
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/
305
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/
109
306
  # RETURNS: JSON array of Post data blocks containing the properties for all the post
110
307
  def get_forum_topic_posts(org_unit_id, forum_id, topic_id, page_size = 0, page_number = 0,
111
308
  threads_only = nil, thread_id = 0, sort = '')
112
309
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/?"
113
- path += "pageSize=#{page_size}&" unless page_size == 0
114
- path += "pageNumber=#{page_number}&" unless page_number == 0
310
+ path += "pageSize=#{page_size}&" unless page_size.zero?
311
+ path += "pageNumber=#{page_number}&" unless page_number.zero?
115
312
  path += "threadsOnly=#{threads_only}&" unless threads_only.nil?
116
- path += "threadId=#{thread_id}&" unless thread_id == 0
313
+ path += "threadId=#{thread_id}&" unless thread_id.zero?
117
314
  path += "sort=#{sort}" unless sort == ''
118
315
  _get(path)
119
316
  # RETURNS: JSON array of Post data blocks containing the properties for all the post
120
317
  end
121
318
 
122
319
  # REVIEW: Retrieve a particular post in a discussion forum topic.
123
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
320
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
124
321
  def get_forum_topic_post(org_unit_id, forum_id, topic_id, post_id)
125
322
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
126
323
  _get(path)
@@ -128,15 +325,15 @@ def get_forum_topic_post(org_unit_id, forum_id, topic_id, post_id)
128
325
  end
129
326
 
130
327
  # REVIEW: Retrieve the approval status for a particular post in a discussion forum topic.
131
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Approval
328
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval
132
329
  def get_forum_topic_post_approval_status(org_unit_id, forum_id, topic_id, post_id)
133
330
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval"
134
331
  _get(path)
135
332
  # RETURNS: ApprovalData JSON data block
136
333
  end
137
334
 
138
- # TODO: Retrieve the flagged status for a particular post in a discussion forum topic.
139
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Flag
335
+ # REVIEW: Retrieve the flagged status for a particular post in a discussion forum topic.
336
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag
140
337
  def get_forum_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id)
141
338
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag"
142
339
  _get(path)
@@ -144,7 +341,7 @@ def get_forum_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id
144
341
  end
145
342
 
146
343
  # REVIEW: Retrieve the rating data for a particular post in a discussion forum topic.
147
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating
344
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating
148
345
  def get_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
149
346
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating"
150
347
  _get(path)
@@ -152,7 +349,7 @@ def get_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
152
349
  end
153
350
 
154
351
  # REVIEW: Retrieve the current user context’s rating data for a particular post in a discussion forum topic.
155
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
352
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
156
353
  def get_current_user_forum_topic_post_rating_data(org_unit_id, forum_id, topic_id, post_id)
157
354
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
158
355
  _get(path)
@@ -160,7 +357,7 @@ def get_current_user_forum_topic_post_rating_data(org_unit_id, forum_id, topic_i
160
357
  end
161
358
 
162
359
  # REVIEW: Retrieve the current read status for a particular post in a discussion forum topic.
163
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/ReadStatus
360
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus
164
361
  def get_forum_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id)
165
362
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus"
166
363
  _get(path)
@@ -168,7 +365,7 @@ def get_forum_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id)
168
365
  end
169
366
 
170
367
  # REVIEW: Retrieve all the vote data for a particular post in a discussion forum topic.
171
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes
368
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes
172
369
  def get_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
173
370
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes"
174
371
  _get(path)
@@ -176,24 +373,132 @@ def get_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
176
373
  end
177
374
 
178
375
  # REVIEW: Retrieve the current user’s vote data for a particular post in a discussion forum topic.
179
- # => GET /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes/MyVote
376
+ # => GET /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote
180
377
  def get_current_user_forum_topic_post_vote_data(org_unit_id, forum_id, topic_id, post_id)
181
378
  path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote"
182
379
  _get(path)
183
380
  # RETURNS: UserVoteData JSON data block
184
381
  end
185
382
 
186
- # TODO: Create a new post in a discussion forum topic.
187
- # => POST /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/
188
- # TODO: Update a particular post in a discussion forum topic.
189
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)
190
- # TODO: Update the approval status of a particular post in a discussion forum topic.
191
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Approval
192
- # TODO: Update the flagged status of a particular post in a discussion forum topic.
193
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Flag
194
- # TODO: Update the current user context’s rating for a particular post in a discussion forum topic.
195
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Rating/MyRating
196
- # TODO: Update the read status of a particular post in a discussion forum topic.
197
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/ReadStatus
198
- # TODO: Update a discussion forum topic post’s vote data for the current user.
199
- # => PUT /d2l/api/le/(version)/(orgUnitId)/discussions/forums/(forumId)/topics/(topicId)/posts/(postId)/Votes/MyVote
383
+ def check_create_post_data_validity(create_post_data)
384
+ schema = {
385
+ 'type' => 'object',
386
+ 'required' => %w(ParentPostId Subject Message IsAnonymous),
387
+ 'properties' =>
388
+ {
389
+ 'ParentPostId' => { 'type' => %w(integer null) },
390
+ 'Subject' => { 'type' => "string" },
391
+ 'Message' =>
392
+ {
393
+ 'type' => 'object',
394
+ 'properties' =>
395
+ {
396
+ "Content" => { 'type' => "string" },
397
+ "Type" => { 'type' => "string" }
398
+ }
399
+ },
400
+ 'IsAnonymous' => { 'type' => 'boolean' }
401
+ }
402
+ }
403
+ JSON::Validator.validate!(schema, create_post_data, validate_schema: true)
404
+ end
405
+
406
+ # REVIEW: Create a new post in a discussion forum topic.
407
+ # => POST /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/
408
+ # NOTE: No file attachments? Send it normally :)
409
+ # NOTE: File attachments? Send using Multipart/Mixed body conforming to RFC2388
410
+ # RETURNS: Post JSON data block
411
+ def create_topic_post(org_unit_id, forum_id, topic_id, create_post_data, files = [])
412
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/"
413
+ payload = {
414
+ "ParentPostId" => nil, # integer or nil
415
+ "Subject" => "",
416
+ "Message" => {
417
+ "Content" => "",
418
+ "Type" => "Text|Html"
419
+ },
420
+ "IsAnonymous" => false
421
+ }.merge!(create_post_data)
422
+ check_create_post_data_validity(payload)
423
+ if files == []
424
+ # can do a simple POST request.
425
+ _post(path, payload)
426
+ else
427
+ # Have to do multipart/mixed body custom POST request.
428
+ _upload_post_data(path, payload, files, "POST")
429
+ end
430
+ end
431
+
432
+ # REVIEW: Update a particular post in a discussion forum topic.
433
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}
434
+ # RETURNS: Post JSON data block
435
+ def update_topic_post(org_unit_id, forum_id, topic_id, post_id, create_post_data)
436
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}"
437
+ payload = {
438
+ "ParentPostId" => nil, # integer or nil
439
+ "Subject" => "",
440
+ "Message" => {
441
+ "Content" => "",
442
+ "Type" => "Text|Html"
443
+ },
444
+ "IsAnonymous" => false
445
+ }.merge!(create_post_data)
446
+ check_create_post_data_validity(payload)
447
+ _put(path, payload)
448
+ end
449
+
450
+ # REVIEW: Update the approval status of a particular post in a discussion forum topic.
451
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval
452
+ # RETURNS: ApprovalData JSON data block
453
+ def update_topic_post_approval_status(org_unit_id, forum_id, topic_id, post_id, is_approved)
454
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Approval"
455
+ raise ArgumentError, "Argument 'is_approved' is not a boolean value." unless is_approved == true || is_approved == false
456
+ payload = { "IsApproved" => is_approved }
457
+ _put(path, payload)
458
+ end
459
+
460
+
461
+ # REVIEW: Update the flagged status of a particular post in a discussion forum topic.
462
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag
463
+ # RETURNS: FlagData JSON data block
464
+ def update_topic_post_flagged_status(org_unit_id, forum_id, topic_id, post_id, is_flagged)
465
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Flag"
466
+ raise ArgumentError, "Argument 'is_flagged' is not a boolean value." unless is_flagged == true || is_flagged == false
467
+ payload = { "IsFlagged" => is_flagged }
468
+ _put(path, payload)
469
+ end
470
+
471
+ # REVIEW: Update the current user context’s rating for a particular post in a discussion forum topic.
472
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating
473
+ # RETURNS: UserRatingData JSON data block
474
+ def update_topic_post_current_user_rating(org_unit_id, forum_id, topic_id, post_id, rating)
475
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Rating/MyRating"
476
+ raise ArgumentError, "Argument 'rating' is not a number or null value." unless rating.is_a?(Numeric) || rating.nil?
477
+ payload = { "Rating" => rating }
478
+ _put(path, payload)
479
+ end
480
+
481
+ # REVIEW: Update the read status of a particular post in a discussion forum topic.
482
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus
483
+ # RETURNS: ReadStatusData JSON data block
484
+ def update_topic_post_read_status(org_unit_id, forum_id, topic_id, post_id, is_read)
485
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/ReadStatus"
486
+ raise ArgumentError, "Argument 'is_read' is not a boolean value." unless is_read == true || is_read == false
487
+ payload = { "IsRead" => is_read }
488
+ _put(path, payload)
489
+ end
490
+
491
+ # REVIEW: Update a discussion forum topic post’s vote data for the current user.
492
+ # => PUT /d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote
493
+ # RETURNS: ??
494
+ def update_topic_post_current_user_vote_data(org_unit_id, forum_id, topic_id, post_id, vote)
495
+ path = "/d2l/api/le/#{$le_ver}/#{org_unit_id}/discussions/forums/#{forum_id}/topics/#{topic_id}/posts/#{post_id}/Votes/MyVote"
496
+ unless vote.is_a? String
497
+ raise ArgumentError, "Argument 'vote' is not a string value."
498
+ else
499
+ payload = {
500
+ "Vote" => vote
501
+ }
502
+ _put(path, payload)
503
+ end
504
+ end