| Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
|---|---|---|---|---|
| app/models/group.rb | 126 | 80 | 92.06%
|
88.75%
|
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 require File.join(File.dirname(__FILE__), '..', '..', |
2 'lib', 'repo', 'repository') |
3 require 'csv_invalid_line_error' |
4 |
5 # Maintains group information for a given user on a specific assignment |
6 class Group < ActiveRecord::Base |
7 |
8 after_create :set_repo_name, :build_repository |
9 |
10 has_many :groupings |
11 has_many :submissions, :through => :groupings |
12 has_many :student_memberships, :through => :groupings |
13 has_many :ta_memberships, |
14 :class_name => "TaMembership", |
15 :through => :groupings |
16 has_many :assignments, :through => :groupings |
17 |
18 |
19 validates_presence_of :group_name |
20 validates_uniqueness_of :group_name |
21 validates_length_of :group_name, :maximum => 30, :message => "is too long" |
22 |
23 # prefix used for autogenerated group_names |
24 AUTOGENERATED_PREFIX = "group_" |
25 |
26 # Set repository name in database after a new group is created |
27 def set_repo_name |
28 # If repo_name has been set already, use this name instead |
29 # of the autogenerated name. |
30 if self.repo_name.nil? |
31 self.repo_name = get_autogenerated_group_name |
32 end |
33 self.save(:validate => false) # need to save! |
34 end |
35 |
36 # Returns the repository name for this group |
37 def repository_name |
38 return self.repo_name |
39 end |
40 |
41 # Returns an autogenerated name for the group using Group::AUTOGENERATED_PREFIX |
42 # This only works, after a barebone group record has been created in the database |
43 def get_autogenerated_group_name |
44 return Group::AUTOGENERATED_PREFIX + self.id.to_s.rjust(4, "0") |
45 end |
46 |
47 def grouping_for_assignment(aid) |
48 return groupings.first(:conditions => {:assignment_id => aid}) |
49 end |
50 |
51 # Returns the URL for externally accessible repos |
52 def repository_external_access_url |
53 return MarkusConfigurator.markus_config_repository_external_base_url + "/" + repository_name |
54 end |
55 |
56 def repository_admin? |
57 return MarkusConfigurator.markus_config_repository_admin? |
58 end |
59 |
60 # Returns configuration for repository |
61 # configuration |
62 def repository_config |
63 conf = Hash.new |
64 conf["IS_REPOSITORY_ADMIN"] = MarkusConfigurator.markus_config_repository_admin? |
65 conf["REPOSITORY_PERMISSION_FILE"] = MarkusConfigurator.markus_config_repository_permission_file |
66 conf["REPOSITORY_STORAGE"] = MarkusConfigurator.markus_config_repository_storage |
67 return conf |
68 end |
69 |
70 def build_repository |
71 # create repositories and write permissions if and only if we are admin |
72 return true if !MarkusConfigurator.markus_config_repository_admin? |
73 |
74 # This might cause repository collision errors, because when the group |
75 # maximum for an assignment is set to be one, the student's username |
76 # will be used as the repository name. This will raise a RepositoryCollision |
77 # if an instructor uses a csv file with a student appearing as the only member of |
78 # two different groups (remember: uploading via csv purges old groupings). |
79 # |
80 # Because we use the group id as part of the repository name in all other cases, |
81 # a repo collision *should* never occur then. |
82 # |
83 # For more info about the exception |
84 # See 'self.create' of lib/repo/subversion_repository.rb. |
85 begin |
86 Repository.get_class(MarkusConfigurator.markus_config_repository_type, self.repository_config).create(File.join(MarkusConfigurator.markus_config_repository_storage, repository_name)) |
87 rescue Repository::RepositoryCollision => e |
88 # log the collision |
89 errors.add(:base, self.repo_name) |
90 m_logger = MarkusLogger.instance |
91 m_logger.log("Creating group '#{self.group_name}' caused repository collision " + |
92 "(Repository name was: '#{self.repo_name}'). Error message: '#{e.message}'", |
93 MarkusLogger::ERROR) |
94 end |
95 |
96 # Each admin user will have read and write permissions on each repo |
97 user_permissions = {} |
98 Admin.all.each do |admin| |
99 user_permissions[admin.user_name] = Repository::Permission::READ_WRITE |
100 end |
101 # Each grader will have read and write permissions on each repo |
102 Ta.all.each do |ta| |
103 user_permissions[ta.user_name] = Repository::Permission::READ_WRITE |
104 end |
105 group_repo = Repository.get_class(MarkusConfigurator.markus_config_repository_type, self.repository_config) |
106 group_repo.set_bulk_permissions(File.join(MarkusConfigurator.markus_config_repository_storage, self.repository_name), user_permissions) |
107 return true |
108 end |
109 |
110 # Return a repository object, if possible |
111 def repo |
112 repo_loc = File.join(MarkusConfigurator.markus_config_repository_storage, self.repository_name) |
113 if Repository.get_class(MarkusConfigurator.markus_config_repository_type, self.repository_config).repository_exists?(repo_loc) |
114 return Repository.get_class(MarkusConfigurator.markus_config_repository_type, self.repository_config).open(repo_loc) |
115 else |
116 raise "Repository not found and MarkUs not in authoritative mode!" # repository not found, and we are not repo-admin |
117 end |
118 end |
119 |
120 #Yields a repository object, if possible, and closes it after it is finished |
121 def access_repo |
122 repository = self.repo |
123 yield repository |
124 repository.close() |
125 end |
126 end |
Generated on Sun Feb 05 00:08:07 -0500 2012 with rcov 0.9.10