| Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
|---|---|---|---|---|
| app/models/student.rb | 288 | 209 | 97.57%
|
96.65%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 class Student < User |
2 |
3 has_many :accepted_groupings, :class_name => 'Grouping', :through => :memberships, :conditions => {'memberships.membership_status' => [StudentMembership::STATUSES[:accepted], StudentMembership::STATUSES[:inviter]]}, :source => :grouping |
4 |
5 has_many :pending_groupings, :class_name => 'Grouping', :through => :memberships, :conditions => {'memberships.membership_status' => StudentMembership::STATUSES[:pending]}, :source => :grouping |
6 |
7 has_many :rejected_groupings, :class_name => 'Grouping', :through => :memberships, :conditions => {'memberships.membership_status' => StudentMembership::STATUSES[:rejected]}, :source => :grouping |
8 |
9 has_many :student_memberships, :foreign_key => 'user_id' |
10 |
11 has_many :grace_period_deductions, :through => :memberships |
12 |
13 belongs_to :section |
14 accepts_nested_attributes_for :section |
15 |
16 validates_numericality_of :grace_credits, :only_integer => true, |
17 :greater_than_or_equal_to => 0 |
18 |
19 CSV_UPLOAD_ORDER = USER_STUDENT_CSV_UPLOAD_ORDER |
20 SESSION_TIMEOUT = USER_STUDENT_SESSION_TIMEOUT |
21 |
22 # Returns true if this student has a Membership in a Grouping for an |
23 # Assignment with id 'aid', where that Membership.membership_status is either |
24 # 'accepted' or 'inviter' |
25 def has_accepted_grouping_for?(aid) |
26 return !accepted_grouping_for(aid).nil? |
27 end |
28 |
29 # Returns the Grouping for an Assignment with id 'aid' if this Student has |
30 # a Membership in that Grouping where the membership.status is 'accepted' |
31 # or 'inviter' |
32 def accepted_grouping_for(aid) |
33 return accepted_groupings.find_by_assignment_id(aid) |
34 end |
35 |
36 def has_pending_groupings_for?(aid) |
37 return (pending_groupings_for(aid).size > 0) |
38 end |
39 |
40 def pending_groupings_for(aid) |
41 return pending_groupings.find_all_by_assignment_id(aid) |
42 end |
43 |
44 def remaining_grace_credits |
45 return @remaining_grace_credits if !@remaining_grace_credits.nil? |
46 total_deductions = 0 |
47 grace_period_deductions.each do |grace_period_deduction| |
48 total_deductions += grace_period_deduction.deduction |
49 end |
50 @remaining_grace_credits = grace_credits - total_deductions |
51 end |
52 |
53 def display_for_note |
54 return user_name + ": " + last_name+", " + first_name |
55 end |
56 |
57 # return pending memberships for a specific assignment |
58 def pending_memberships_for(aid) |
59 groupings = self.pending_groupings_for(aid) |
60 if !groupings.nil? |
61 pending_memberships = [] |
62 groupings.each do |grouping| |
63 pending_memberships.push(StudentMembership.find_by_grouping_id_and_user_id(grouping.id, self.id)) |
64 end |
65 return pending_memberships |
66 end |
67 return nil |
68 end |
69 |
70 |
71 # Returns the Membership for a Grouping for an Assignment with id 'aid' if |
72 # this Student is a member with either 'accepted' or 'invitier' membership |
73 # status |
74 |
75 def memberships_for(aid) |
76 @student = self |
77 @memberships = StudentMembership.find(:all, :conditions => {:user_id => @student.id}) |
78 @memberships.each do |m| |
79 if m.grouping.assignment_id != aid |
80 @memberships.delete(m) |
81 end |
82 end |
83 return @memberships |
84 end |
85 |
86 # invites a student |
87 def invite(gid) |
88 if !self.hidden |
89 membership = StudentMembership.new |
90 membership.grouping_id = gid; |
91 membership.membership_status = StudentMembership::STATUSES[:pending] |
92 membership.user_id = self.id |
93 membership.save |
94 # update repo permissions (for accepted memberships - includes inviter) |
95 # if grouping is valid |
96 grouping = Grouping.find(gid) |
97 grouping.update_repository_permissions |
98 end |
99 end |
100 |
101 def destroy_all_pending_memberships(aid) |
102 self.pending_groupings_for(aid).each do |grouping| |
103 membership = grouping.student_memberships.find_by_user_id(self.id) |
104 membership.destroy |
105 end |
106 end |
107 |
108 # creates a group and a grouping for a student to work alone, for |
109 # assignment aid |
110 def create_group_for_working_alone_student(aid) |
111 ActiveRecord::Base.transaction do |
112 @assignment = Assignment.find(aid) |
113 @grouping = Grouping.new |
114 @grouping.assignment_id = @assignment.id |
115 if !Group.find(:first, :conditions => {:group_name => self.user_name}).nil? |
116 @group = Group.find(:first, :conditions => {:group_name => self.user_name}) |
117 else |
118 @group = Group.new(:group_name => self.user_name) |
119 # We want to have the user_name as repository name, |
120 # so we have to set the repo_name before we save the group. |
121 # We do that only if the assignment is set up to be a |
122 # non-web-submit assignment. |
123 if @assignment.allow_web_submits == false |
124 @group.repo_name = self.user_name |
125 end |
126 if !@group.save |
127 m_logger = MarkusLogger.instance |
128 m_logger.log("Could not create a group for Student '#{self.user_name}'. The group was #{@group.inspect} - errors: #{@group.errors.inspect}", MarkusLogger::ERROR) |
129 raise "Sorry! For some reason, your group could not be created. Please wait a few seconds, then hit refresh to try again. If you come back to this page, you should inform the course instructor." |
130 end |
131 end |
132 |
133 @grouping.group = @group |
134 if !@grouping.save |
135 m_logger = MarkusLogger.instance |
136 m_logger.log("Could not create a grouping for Student '#{self.user_name}'. The grouping was: #{@grouping.inspect} - errors: #{@grouping.errors.inspect}", MarkusLogger::ERROR) |
137 raise "Sorry! For some reason, your grouping could not be created. Please wait a few seconds, and hit refresh to try again. If you come back to this page, you should inform the course instructor." |
138 end |
139 |
140 # We give students the tokens for the test framework |
141 @grouping.give_tokens |
142 |
143 # Create the membership |
144 @member = StudentMembership.new(:grouping_id => @grouping.id, |
145 :membership_status => StudentMembership::STATUSES[:inviter], |
146 :user_id => self.id) |
147 @member.save |
148 |
149 # Destroy all the other memebrships for this assignment |
150 self.destroy_all_pending_memberships(@assignment.id) |
151 |
152 # Update repo permissions if need be. This has to happen |
153 # after memberships have been established. |
154 @grouping.update_repository_permissions |
155 end |
156 return true |
157 end |
158 |
159 def create_autogenerated_name_group(aid) |
160 assignment = Assignment.find(aid) |
161 if !assignment.group_name_autogenerated |
162 raise "Assignment does not allow for groups with autogenerated names" |
163 end |
164 |
165 group = Group.new |
166 group.save(:validate => false) |
167 group.group_name = group.get_autogenerated_group_name |
168 group.save |
169 |
170 grouping = Grouping.new |
171 grouping.assignment_id = aid |
172 grouping.group_id = group.id |
173 grouping.save |
174 |
175 # write repo permissions if need be |
176 grouping.update_repository_permissions |
177 |
178 member = StudentMembership.new(:grouping_id => grouping.id, :membership_status => StudentMembership::STATUSES[:inviter], :user_id => self.id) |
179 member.save |
180 self.destroy_all_pending_memberships(aid) |
181 end |
182 |
183 # This method is called, when a student joins a group(ing) |
184 def join(gid) |
185 membership = StudentMembership.find_by_grouping_id_and_user_id(gid, self.id) |
186 membership.membership_status = 'accepted' |
187 membership.save |
188 |
189 grouping = Grouping.find(gid) |
190 # write repo permissions if need be |
191 grouping.update_repository_permissions |
192 |
193 if grouping.is_valid? |
194 # We give students the tokens for the test framework |
195 grouping.give_tokens |
196 end |
197 |
198 other_memberships = self.pending_memberships_for(grouping.assignment_id) |
199 other_memberships.each do |m| |
200 m.membership_status = 'rejected' |
201 m.save |
202 end |
203 end |
204 |
205 # Hides a list of students and revokes repository |
206 # permissions (when exposed externally) |
207 def self.hide_students(student_id_list) |
208 update_list = {} |
209 student_id_list.each do |student_id| |
210 update_list[student_id] = {:hidden => true} |
211 # update repo permissions appropriately |
212 memberships = StudentMembership.find_by_user_id(student_id) |
213 if !memberships.nil? |
214 if !memberships.instance_of?(Array) |
215 memberships = [memberships] |
216 end |
217 student = Student.find(student_id) |
218 memberships.each do |membership| |
219 group = membership.grouping.group |
220 group.access_repo do |repo| |
221 if membership.grouping.repository_external_commits_only? && membership.grouping.is_valid? |
222 begin |
223 repo.remove_user(student.user_name) # revoke repo permissions |
224 rescue Repository::UserNotFound |
225 # ignore case when user isn't there any more |
226 end |
227 end |
228 end |
229 end |
230 end |
231 end |
232 Student.update(update_list.keys, update_list.values) |
233 end |
234 |
235 # "Unhides" students not visible and grants repository |
236 # permissions (when exposed externally) |
237 def self.unhide_students(student_id_list) |
238 update_list = {} |
239 student_id_list.each do |student_id| |
240 update_list[student_id] = {:hidden => false} |
241 # update repo permissions appropriately |
242 memberships = StudentMembership.find_by_user_id(student_id) |
243 if !memberships.nil? |
244 if !memberships.instance_of?(Array) |
245 memberships = [memberships] |
246 end |
247 student = Student.find(student_id) |
248 memberships.each do |membership| |
249 group = membership.grouping.group |
250 group.access_repo do |repo| |
251 if membership.grouping.repository_external_commits_only? && membership.grouping.is_valid? |
252 begin |
253 repo.add_user(student.user_name, Repository::Permission::READ_WRITE) # grant repo permissions |
254 rescue Repository::UserAlreadyExistent |
255 # ignore case if user has permissions already |
256 end |
257 end |
258 end |
259 end |
260 end |
261 end |
262 Student.update(update_list.keys, update_list.values) |
263 end |
264 |
265 def self.give_grace_credits(student_ids, number_of_grace_credits) |
266 students = Student.find(student_ids) |
267 students.each do |student| |
268 student.grace_credits += number_of_grace_credits.to_i |
269 if student.grace_credits < 0 |
270 student.grace_credits = 0 |
271 end |
272 student.save |
273 end |
274 end |
275 |
276 # Returns true when the student has a section |
277 def has_section? |
278 return !self.section.nil? |
279 end |
280 |
281 # Updates the section of a list of students |
282 def self.update_section(students_ids, nsection) |
283 students_ids.each do |sid| |
284 Student.update(sid, {:section_id => nsection}) |
285 end |
286 end |
287 |
288 end |
Generated on Sun Feb 05 00:08:07 -0500 2012 with rcov 0.9.10