Skip to content

Commit b2c2049

Browse files
committed
include other IDs in assignment points CSV; add test
1 parent 67746ab commit b2c2049

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

src/main/kotlin/ch/uzh/ifi/access/controller/CourseController.kt

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -195,36 +195,14 @@ class CourseController(
195195
@PathVariable courseSlug: String,
196196
response: HttpServletResponse
197197
) {
198-
val pointsData = courseService.getStudentsWithAssignmentPoints(courseSlug)
198+
val rows = courseService.getStudentsWithAssignmentPoints(courseSlug)
199199
response.apply {
200200
setHeader("Content-Disposition", "attachment; filename=access_points_${courseSlug}.csv")
201201
contentType = "text/csv"
202202
}
203203
response.outputStream.writer(StandardCharsets.UTF_8).use { writer ->
204-
val pointsByUser = pointsData.groupBy { it.userId }
205-
val assignments = pointsData
206-
.map { it.ordinalNum }
207-
.distinct()
208-
.sortedBy { ordinalNum ->
209-
pointsData
210-
.filter { it.ordinalNum == ordinalNum }
211-
.minByOrNull { it.ordinalNum ?: Long.MAX_VALUE }
212-
?.ordinalNum ?: Long.MAX_VALUE
213-
}
214-
val header = listOf("user_id") + assignments.map { "as${it}" } + listOf("total")
215-
writer.write(header.joinToString(",") { (it.toString()) })
216-
writer.appendLine()
217-
pointsByUser.forEach { (userId, userAssignmentPoints) ->
218-
val row = mutableListOf(userId)
219-
assignments.forEach { ordinalNum ->
220-
val points = userAssignmentPoints
221-
.find { it.ordinalNum == ordinalNum }
222-
?.totalPoints
223-
?: 0.0
224-
row.add(points.toString())
225-
}
226-
row.add(userAssignmentPoints.sumOf { it.totalPoints ?: 0.0 }.toString())
227-
writer.write(row.joinToString(","))
204+
rows.forEach { row ->
205+
writer.write(row.joinToString(",") { (it.toString()) })
228206
writer.appendLine()
229207
}
230208
writer.flush()

src/main/kotlin/ch/uzh/ifi/access/service/CourseService.kt

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class CourseService(
100100
fun getStudentsWithAssignmentPoints(
101101
courseSlug: String,
102102
withAssistants: Boolean = false
103-
): List<AssignmentPointsDTO> {
103+
): MutableList<List<String?>> {
104104
val course = getCourseBySlug(courseSlug)
105105
val names = if (withAssistants) {
106106
course.registeredStudents + course.assistants + course.supervisors
@@ -111,7 +111,7 @@ class CourseService(
111111
val userIds = course.registeredStudents.associateWith { roleService.getUserId(it) }
112112
val userIdsInverse = userIds.map { (k, v) -> v to k }.toMap()
113113
val userNames = users.map { (k, v) -> k to v?.username }.toMap()
114-
return courseRepository.getParticipantsAssignmentPoints(
114+
val pointsData = courseRepository.getParticipantsAssignmentPoints(
115115
courseSlug,
116116
userIds.values.filterNotNull().toTypedArray()
117117
).map {
@@ -122,6 +122,40 @@ class CourseService(
122122
it.totalPoints,
123123
)
124124
}
125+
val pointsByUser = pointsData.groupBy { it.userId }
126+
val assignments = pointsData
127+
.map { it.ordinalNum }
128+
.distinct()
129+
.sortedBy { ordinalNum ->
130+
pointsData
131+
.filter { it.ordinalNum == ordinalNum }
132+
.minByOrNull { it.ordinalNum ?: Long.MAX_VALUE }
133+
?.ordinalNum ?: Long.MAX_VALUE
134+
}
135+
val rows = mutableListOf(
136+
mutableListOf<String?>(
137+
"username",
138+
"registered_as",
139+
"other_ids"
140+
) + assignments.map { "as${it}" } + listOf("total"))
141+
pointsByUser.forEach { (userId, userAssignmentPoints) ->
142+
val registrationID = userIdsInverse.getOrDefault(userId!!, userId)
143+
val row = mutableListOf(
144+
userId,
145+
registrationID,
146+
roleService.getRegistrationIDCandidates(userId).minus(setOf(userId, registrationID)).joinToString(" ")
147+
)
148+
assignments.forEach { ordinalNum ->
149+
val points = userAssignmentPoints
150+
.find { it.ordinalNum == ordinalNum }
151+
?.totalPoints
152+
?: 0.0
153+
row.add(points.toString())
154+
}
155+
row.add(userAssignmentPoints.sumOf { it.totalPoints ?: 0.0 }.toString())
156+
rows.add(row)
157+
}
158+
return rows
125159
}
126160

127161
fun getCourseBySlug(courseSlug: String): Course {

src/test/kotlin/ch/uzh/ifi/access/api/AfterSubmissionTests.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ch.uzh.ifi.access.api
22

3+
import ch.uzh.ifi.access.AccessUser
34
import ch.uzh.ifi.access.BaseTest
45
import org.hamcrest.Matchers.*
56
import org.junit.jupiter.api.*
@@ -159,4 +160,22 @@ class AfterSubmissionTests(@Autowired val mvc: MockMvc) : BaseTest() {
159160
.andExpect(jsonPath(path, hasItem(containsString("a=1;b=0;c=0;d=0"))))
160161
}
161162

163+
@Test
164+
@Order(0)
165+
@AccessUser(
166+
username = "supervisor@uzh.ch",
167+
authorities = ["supervisor", "access-mock-course-supervisor", "access-mock-course"]
168+
)
169+
fun `Can download CSV with assignment points`() {
170+
mvc.perform(
171+
get("/courses/access-mock-course/assignmentPoints")
172+
.contentType("text/csv")
173+
.with(csrf())
174+
)
175+
.andExpect(status().isOk)
176+
.andExpect(content().contentType("text/csv"))
177+
.andExpect(content().string(containsString("username,registered_as,other_ids,")))
178+
.andExpect(content().string(containsString("student@uzh.ch,,2.0,2.0")))
179+
}
180+
162181
}

0 commit comments

Comments
 (0)