github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/web/groups_test.go (about) 1 package web_test 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/google/go-cmp/cmp" 8 "google.golang.org/protobuf/testing/protocmp" 9 10 "github.com/quickfeed/quickfeed/internal/qtest" 11 "github.com/quickfeed/quickfeed/qf" 12 ) 13 14 func TestNewGroup(t *testing.T) { 15 db, cleanup := qtest.TestDB(t) 16 defer cleanup() 17 18 client, tm, _ := MockClientWithUser(t, db) 19 20 admin := qtest.CreateFakeUser(t, db) 21 var course qf.Course 22 // only created 1 directory, if we had created two directories ID would be 2 23 course.ScmOrganizationID = 1 24 course.ScmOrganizationName = "test" 25 if err := db.CreateCourse(admin.ID, &course); err != nil { 26 t.Fatal(err) 27 } 28 user := qtest.CreateFakeUser(t, db) 29 qtest.EnrollStudent(t, db, user, &course) 30 31 ctx := context.Background() 32 // current user must be in the group being created 33 createGroupRequest := qtest.RequestWithCookie(&qf.Group{Name: "Heins-Group", CourseID: course.ID, Users: []*qf.User{{ID: user.ID}}}, Cookie(t, tm, user)) 34 wantGroup, err := client.CreateGroup(ctx, createGroupRequest) 35 if err != nil { 36 t.Error(err) 37 } 38 gotGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{CourseID: course.ID, GroupID: wantGroup.Msg.ID}, Cookie(t, tm, user))) 39 if err != nil { 40 t.Error(err) 41 } 42 if diff := cmp.Diff(wantGroup.Msg, gotGroup.Msg, protocmp.Transform()); diff != "" { 43 t.Errorf("CreateGroup() mismatch (-wantGroup +gotGroup):\n%s", diff) 44 } 45 } 46 47 func TestCreateGroupWithMissingFields(t *testing.T) { 48 db, cleanup := qtest.TestDB(t) 49 defer cleanup() 50 51 client, tm, _ := MockClientWithUser(t, db) 52 53 admin := qtest.CreateFakeUser(t, db) 54 var course qf.Course 55 // only created 1 directory, if we had created two directories ID would be 2 56 course.ScmOrganizationID = 1 57 if err := db.CreateCourse(admin.ID, &course); err != nil { 58 t.Fatal(err) 59 } 60 user := qtest.CreateFakeUser(t, db) 61 qtest.EnrollStudent(t, db, user, &course) 62 63 users := []*qf.User{{ID: user.ID}} 64 65 ctx := context.Background() 66 67 // current user must be in the group being created 68 group_wo_course_id := qtest.RequestWithCookie(&qf.Group{Name: "Hein's Group", Users: users}, Cookie(t, tm, user)) 69 _, err := client.CreateGroup(ctx, group_wo_course_id) 70 if err == nil { 71 t.Fatal("expected CreateGroup to fail without a course ID") 72 } 73 group_wo_name := qtest.RequestWithCookie(&qf.Group{CourseID: course.ID, Users: users}, Cookie(t, tm, user)) 74 if group_wo_name.Msg.IsValid() { 75 // emulate CreateGroup check without name 76 t.Fatal("expected CreateGroup to fail without group name") 77 } 78 group_wo_users := qtest.RequestWithCookie(&qf.Group{Name: "Hein's Group", CourseID: course.ID}, Cookie(t, tm, user)) 79 _, err = client.CreateGroup(ctx, group_wo_users) 80 if err == nil { 81 t.Fatal("expected CreateGroup to fail without users") 82 } 83 } 84 85 func TestNewGroupTeacherCreator(t *testing.T) { 86 db, cleanup := qtest.TestDB(t) 87 defer cleanup() 88 89 client, tm, _ := MockClientWithUser(t, db) 90 91 admin := qtest.CreateFakeUser(t, db) 92 var course qf.Course 93 // only created 1 directory, if we had created two directories ID would be 2 94 course.ScmOrganizationID = 1 95 if err := db.CreateCourse(admin.ID, &course); err != nil { 96 t.Fatal(err) 97 } 98 99 teacher := qtest.CreateFakeUser(t, db) 100 qtest.EnrollTeacher(t, db, teacher, &course) 101 102 user := qtest.CreateFakeUser(t, db) 103 qtest.EnrollStudent(t, db, user, &course) 104 105 users := []*qf.User{{ID: user.ID}} 106 ctx := context.Background() 107 108 // current user must be in the group being created 109 wantGroup, err := client.CreateGroup(ctx, qtest.RequestWithCookie(&qf.Group{Name: "HeinsGroup", CourseID: course.ID, Users: users}, Cookie(t, tm, user))) 110 if err != nil { 111 t.Error(err) 112 } 113 // check that group member (user) can access group 114 groupReq := &qf.GroupRequest{CourseID: course.ID, GroupID: wantGroup.Msg.ID} 115 gotGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(groupReq, Cookie(t, tm, user))) 116 if err != nil { 117 t.Error(err) 118 } 119 // check that teacher can access group 120 _, err = client.GetGroup(ctx, qtest.RequestWithCookie(groupReq, Cookie(t, tm, teacher))) 121 if err != nil { 122 t.Error(err) 123 } 124 // check that admin can access group 125 _, err = client.GetGroup(ctx, qtest.RequestWithCookie(groupReq, Cookie(t, tm, admin))) 126 if err != nil { 127 t.Error(err) 128 } 129 130 if diff := cmp.Diff(wantGroup.Msg, gotGroup.Msg, protocmp.Transform()); diff != "" { 131 t.Errorf("CreateGroup() mismatch (-wantGroup +gotGroup):\n%s", diff) 132 } 133 } 134 135 func TestNewGroupStudentCreateGroupWithTeacher(t *testing.T) { 136 db, cleanup := qtest.TestDB(t) 137 defer cleanup() 138 139 client, tm, _ := MockClientWithUser(t, db) 140 141 admin := qtest.CreateFakeUser(t, db) 142 var course qf.Course 143 // only created 1 directory, if we had created two directories ID would be 2 144 course.ScmOrganizationID = 1 145 if err := db.CreateCourse(admin.ID, &course); err != nil { 146 t.Fatal(err) 147 } 148 149 teacher := qtest.CreateFakeUser(t, db) 150 qtest.EnrollTeacher(t, db, teacher, &course) 151 152 user := qtest.CreateFakeUser(t, db) 153 qtest.EnrollStudent(t, db, user, &course) 154 155 // current user must be in the group being created 156 group_req := qtest.RequestWithCookie(&qf.Group{ 157 Name: "HeinsGroup", 158 CourseID: course.ID, 159 Users: []*qf.User{{ID: user.ID}, {ID: teacher.ID}}, 160 }, Cookie(t, tm, user)) 161 _, err := client.CreateGroup(context.Background(), group_req) 162 if err != nil { 163 t.Error(err) 164 } 165 // we now allow teacher/student groups to be created, 166 // since if undesirable these can be rejected. 167 } 168 169 func TestStudentCreateNewGroupTeacherUpdateGroup(t *testing.T) { 170 db, cleanup := qtest.TestDB(t) 171 defer cleanup() 172 173 client, tm, _ := MockClientWithUser(t, db) 174 175 admin := qtest.CreateFakeUser(t, db) 176 course := qf.Course{ScmOrganizationID: 1, ScmOrganizationName: qtest.MockOrg} 177 if err := db.CreateCourse(admin.ID, &course); err != nil { 178 t.Fatal(err) 179 } 180 181 teacher := qtest.CreateFakeUser(t, db) 182 qtest.EnrollTeacher(t, db, teacher, &course) 183 184 user1 := qtest.CreateFakeUser(t, db) 185 qtest.EnrollStudent(t, db, user1, &course) 186 187 user2 := qtest.CreateFakeUser(t, db) 188 qtest.EnrollStudent(t, db, user2, &course) 189 190 user3 := qtest.CreateFakeUser(t, db) 191 qtest.EnrollStudent(t, db, user3, &course) 192 193 // set user1 in cookie, which is a group member 194 // group with two students 195 createGroupRequest := qtest.RequestWithCookie(&qf.Group{ 196 Name: "HeinsTwoMemberGroup", 197 CourseID: course.ID, 198 Users: []*qf.User{user1, user2}, 199 }, Cookie(t, tm, user1)) 200 201 ctx := context.Background() 202 wantGroup, err := client.CreateGroup(ctx, createGroupRequest) 203 if err != nil { 204 t.Error(err) 205 } 206 207 gotGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 208 CourseID: course.ID, 209 GroupID: wantGroup.Msg.ID, 210 }, Cookie(t, tm, user1))) 211 if err != nil { 212 t.Error(err) 213 } 214 215 if diff := cmp.Diff(wantGroup.Msg, gotGroup.Msg, protocmp.Transform()); diff != "" { 216 t.Errorf("CreateGroup() mismatch (-wantGroup +gotGroup):\n%s", diff) 217 } 218 219 // ******************* Teacher UpdateGroup ******************* 220 221 // set teacher in cookie 222 // group with three students 223 updateGroupRequest := qtest.RequestWithCookie(&qf.Group{ 224 ID: gotGroup.Msg.ID, 225 Name: "Heins3MemberGroup", 226 CourseID: course.ID, 227 Users: []*qf.User{user1, user2, user3}, 228 }, Cookie(t, tm, teacher)) 229 gotUpdatedGroup, err := client.UpdateGroup(ctx, updateGroupRequest) 230 if err != nil { 231 t.Error(err) 232 } 233 234 // check that the group have changed group membership 235 userIDs := make([]uint64, 0) 236 for _, usr := range updateGroupRequest.Msg.Users { 237 userIDs = append(userIDs, usr.ID) 238 } 239 240 grpUsers, err := db.GetUsers(userIDs...) 241 if err != nil { 242 t.Fatal(err) 243 } 244 245 wantGroup = gotGroup 246 wantGroup.Msg.Name = updateGroupRequest.Msg.Name 247 wantGroup.Msg.Users = grpUsers 248 wantGroup.Msg.ScmTeamID = 1 249 // UpdateGroup will autoApprove group on update 250 wantGroup.Msg.Status = qf.Group_APPROVED 251 // Ignore enrollments in check 252 gotUpdatedGroup.Msg.Enrollments = nil 253 wantGroup.Msg.Enrollments = nil 254 255 if diff := cmp.Diff(wantGroup.Msg, gotUpdatedGroup.Msg, protocmp.Transform()); diff != "" { 256 t.Errorf("UpdateGroup() mismatch (-wantGroup +gotUpdatedGroup):\n%s", diff) 257 } 258 259 // ******************* Teacher UpdateGroup ******************* 260 261 // change group to only one student 262 // name must not update because group team and repo already exist 263 updateGroupRequest1 := qtest.RequestWithCookie(&qf.Group{ 264 ID: gotGroup.Msg.ID, 265 Name: "Hein's single member Group", 266 CourseID: course.ID, 267 Users: []*qf.User{user1}, 268 }, Cookie(t, tm, teacher)) 269 gotUpdatedGroup, err = client.UpdateGroup(ctx, updateGroupRequest1) 270 if err != nil { 271 t.Error(err) 272 } 273 // check that the group have changed group membership 274 userIDs = make([]uint64, 0) 275 for _, usr := range updateGroupRequest1.Msg.Users { 276 userIDs = append(userIDs, usr.ID) 277 } 278 279 grpUsers, err = db.GetUsers(userIDs...) 280 if err != nil { 281 t.Fatal(err) 282 } 283 if len(gotUpdatedGroup.Msg.Users) != 1 { 284 t.Errorf("Expected only single member group, got %d members", len(gotUpdatedGroup.Msg.Users)) 285 } 286 wantGroup.Msg = updateGroupRequest.Msg 287 wantGroup.Msg.Users = grpUsers 288 wantGroup.Msg.ScmTeamID = 1 289 // UpdateGroup will autoApprove group on update 290 wantGroup.Msg.Status = qf.Group_APPROVED 291 gotUpdatedGroup.Msg.Enrollments = nil 292 wantGroup.Msg.Enrollments = nil 293 294 if diff := cmp.Diff(wantGroup.Msg, gotUpdatedGroup.Msg, protocmp.Transform()); diff != "" { 295 t.Errorf("UpdateGroup() mismatch (-wantGroup +gotUpdatedGroup):\n%s", diff) 296 } 297 } 298 299 func TestDeleteGroup(t *testing.T) { 300 db, cleanup := qtest.TestDB(t) 301 defer cleanup() 302 303 client, tm, _ := MockClientWithUser(t, db) 304 admin := qtest.CreateFakeCustomUser(t, db, &qf.User{Name: "admin", Login: "admin"}) 305 306 ctx := context.Background() 307 testCourse, err := client.CreateCourse(ctx, qtest.RequestWithCookie(qtest.MockCourses[0], Cookie(t, tm, admin))) 308 if err != nil { 309 t.Error(err) 310 } 311 course := testCourse.Msg 312 313 // create user and enroll as pending (teacher) 314 teacher := qtest.CreateFakeCustomUser(t, db, &qf.User{Name: "teacher", Login: "teacher"}) 315 if _, err := client.CreateEnrollment(ctx, qtest.RequestWithCookie(&qf.Enrollment{ 316 UserID: teacher.ID, 317 CourseID: course.ID, 318 }, Cookie(t, tm, teacher))); err != nil { 319 t.Error(err) 320 } 321 322 // update enrollment from pending->student->teacher; must be done by admin 323 if _, err := client.UpdateEnrollments(ctx, qtest.RequestWithCookie(&qf.Enrollments{ 324 Enrollments: []*qf.Enrollment{ 325 { 326 UserID: teacher.ID, 327 CourseID: course.ID, 328 Status: qf.Enrollment_STUDENT, 329 }, 330 }, 331 }, Cookie(t, tm, admin))); err != nil { 332 t.Error(err) 333 } 334 335 // update enrollment to teacher 336 if _, err := client.UpdateEnrollments(ctx, qtest.RequestWithCookie(&qf.Enrollments{ 337 Enrollments: []*qf.Enrollment{ 338 { 339 UserID: teacher.ID, 340 CourseID: course.ID, 341 Status: qf.Enrollment_TEACHER, 342 }, 343 }, 344 }, Cookie(t, tm, admin))); err != nil { 345 t.Error(err) 346 } 347 348 // create user and enroll as pending (student) 349 user := qtest.CreateFakeCustomUser(t, db, &qf.User{Name: "student", Login: "student"}) 350 if _, err := client.CreateEnrollment(ctx, qtest.RequestWithCookie(&qf.Enrollment{ 351 UserID: user.ID, 352 CourseID: course.ID, 353 }, Cookie(t, tm, user))); err != nil { 354 t.Error(err) 355 } 356 357 // update pending enrollment to student; must be done by teacher 358 if _, err := client.UpdateEnrollments(ctx, qtest.RequestWithCookie(&qf.Enrollments{ 359 Enrollments: []*qf.Enrollment{ 360 { 361 UserID: user.ID, 362 CourseID: course.ID, 363 Status: qf.Enrollment_STUDENT, 364 }, 365 }, 366 }, Cookie(t, tm, teacher))); err != nil { 367 t.Error(err) 368 } 369 370 // create group as student user 371 group := &qf.Group{Name: "TestDeleteGroup", CourseID: course.ID, Users: []*qf.User{user}} 372 respGroup, err := client.CreateGroup(ctx, qtest.RequestWithCookie(group, Cookie(t, tm, user))) 373 if err != nil { 374 t.Fatal(err) 375 } 376 377 // delete group as teacher 378 _, err = client.DeleteGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 379 GroupID: respGroup.Msg.ID, 380 CourseID: course.ID, 381 }, Cookie(t, tm, teacher))) 382 if err != nil { 383 t.Error(err) 384 } 385 } 386 387 func TestGetGroup(t *testing.T) { 388 db, cleanup := qtest.TestDB(t) 389 defer cleanup() 390 391 client, tm, _ := MockClientWithUser(t, db) 392 393 testCourse := qf.Course{ 394 Name: "Distributed Systems", 395 Code: "DAT520", 396 Year: 2018, 397 Tag: "Spring", 398 ScmOrganizationID: 1, 399 } 400 admin := qtest.CreateFakeUser(t, db) 401 if err := db.CreateCourse(admin.ID, &testCourse); err != nil { 402 t.Fatal(err) 403 } 404 405 // create user and enroll as student 406 user := qtest.CreateFakeUser(t, db) 407 qtest.EnrollStudent(t, db, user, &testCourse) 408 409 ctx := context.Background() 410 411 group := &qf.Group{Name: "TestGroup", CourseID: testCourse.ID, Users: []*qf.User{user}} 412 wantGroup, err := client.CreateGroup(ctx, qtest.RequestWithCookie(group, Cookie(t, tm, user))) 413 if err != nil { 414 t.Error(err) 415 } 416 417 gotGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 418 CourseID: testCourse.ID, 419 GroupID: wantGroup.Msg.ID, 420 }, Cookie(t, tm, user))) 421 if err != nil { 422 t.Error(err) 423 } 424 if diff := cmp.Diff(wantGroup.Msg, gotGroup.Msg, protocmp.Transform()); diff != "" { 425 t.Errorf("CreateGroup() mismatch (-wantGroup +gotGroup):\n%s", diff) 426 } 427 } 428 429 func TestPatchGroupStatus(t *testing.T) { 430 db, cleanup := qtest.TestDB(t) 431 defer cleanup() 432 433 client, tm, _ := MockClientWithUser(t, db) 434 435 course := qf.Course{ 436 Name: "Distributed Systems", 437 Code: "DAT520", 438 Year: 2018, 439 Tag: "Spring", 440 ScmOrganizationID: 1, 441 ScmOrganizationName: qtest.MockOrg, 442 ID: 1, 443 } 444 445 admin := qtest.CreateFakeUser(t, db) 446 err := db.CreateCourse(admin.ID, &course) 447 if err != nil { 448 t.Fatal(err) 449 } 450 451 teacher := qtest.CreateFakeUser(t, db) 452 qtest.EnrollTeacher(t, db, teacher, &course) 453 454 if err := db.UpdateUser(&qf.User{ID: teacher.ID, IsAdmin: true}); err != nil { 455 t.Fatal(err) 456 } 457 458 ctx := context.Background() 459 460 user1 := qtest.CreateFakeUser(t, db) 461 user2 := qtest.CreateFakeUser(t, db) 462 463 // enroll users in course and group 464 qtest.EnrollStudent(t, db, user1, &course) 465 qtest.EnrollStudent(t, db, user2, &course) 466 467 group := &qf.Group{ 468 ID: 1, 469 Name: "Test Group", 470 CourseID: course.ID, 471 Users: []*qf.User{user1, user2}, 472 ScmTeamID: 1, 473 } 474 err = db.CreateGroup(group) 475 if err != nil { 476 t.Fatal(err) 477 } 478 // get the group as stored in db with enrollments 479 wantGroup, err := db.GetGroup(group.ID) 480 if err != nil { 481 t.Fatal(err) 482 } 483 484 wantGroup.Status = qf.Group_APPROVED 485 gotGroup, err := client.UpdateGroup(ctx, qtest.RequestWithCookie(wantGroup, Cookie(t, tm, teacher))) 486 if err != nil { 487 t.Error(err) 488 } 489 490 if diff := cmp.Diff(wantGroup, gotGroup.Msg, protocmp.Transform()); diff != "" { 491 t.Errorf("UpdateGroup() mismatch (-wantGroup +gotGroup):\n%s", diff) 492 } 493 } 494 495 func TestGetGroupByUserAndCourse(t *testing.T) { 496 db, cleanup := qtest.TestDB(t) 497 defer cleanup() 498 499 client, tm, _ := MockClientWithUser(t, db) 500 501 course := qf.Course{ 502 Name: "Distributed Systems", 503 Code: "DAT520", 504 Year: 2018, 505 Tag: "Spring", 506 ScmOrganizationID: 1, 507 ID: 1, 508 } 509 510 admin := qtest.CreateFakeUser(t, db) 511 err := db.CreateCourse(admin.ID, &course) 512 if err != nil { 513 t.Fatal(err) 514 } 515 516 ctx := context.Background() 517 518 user1 := qtest.CreateFakeUser(t, db) 519 user2 := qtest.CreateFakeUser(t, db) 520 521 // enroll users in course and group 522 qtest.EnrollStudent(t, db, user1, &course) 523 qtest.EnrollStudent(t, db, user2, &course) 524 525 group := &qf.Group{ 526 CourseID: course.ID, 527 Users: []*qf.User{user1, user2}, 528 } 529 err = db.CreateGroup(group) 530 if err != nil { 531 t.Fatal(err) 532 } 533 534 wantGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 535 CourseID: course.ID, 536 UserID: user1.ID, 537 }, Cookie(t, tm, admin))) 538 if err != nil { 539 t.Error(err) 540 } 541 gotGroup, err := client.GetGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 542 CourseID: course.ID, 543 GroupID: group.ID, 544 }, Cookie(t, tm, admin))) 545 if err != nil { 546 t.Error(err) 547 } 548 if diff := cmp.Diff(wantGroup.Msg, gotGroup.Msg, protocmp.Transform()); diff != "" { 549 t.Errorf("GetGroupByUserAndCourse() mismatch (-wantGroup +gotGroup):\n%s", diff) 550 } 551 } 552 553 func TestDeleteApprovedGroup(t *testing.T) { 554 db, cleanup := qtest.TestDB(t) 555 defer cleanup() 556 557 client, tm, _ := MockClientWithUser(t, db) 558 559 admin := qtest.CreateFakeUser(t, db) 560 course := qtest.MockCourses[0] 561 qtest.CreateCourse(t, db, admin, course) 562 563 user1 := qtest.CreateFakeUser(t, db) 564 user2 := qtest.CreateFakeUser(t, db) 565 566 // enroll users in course and group 567 qtest.EnrollStudent(t, db, user1, course) 568 qtest.EnrollStudent(t, db, user2, course) 569 570 group := &qf.Group{ 571 ID: 1, 572 CourseID: course.ID, 573 Name: "TestGroup", 574 Users: []*qf.User{user1, user2}, 575 } 576 // current user1 must be in the group being created 577 ctx := context.Background() 578 createdGroup, err := client.CreateGroup(ctx, qtest.RequestWithCookie(group, Cookie(t, tm, user1))) 579 if err != nil { 580 t.Error(err) 581 } 582 583 // first approve the group 584 createdGroup.Msg.Status = qf.Group_APPROVED 585 // current user must be teacher for the course 586 if _, err = client.UpdateGroup(ctx, qtest.RequestWithCookie(createdGroup.Msg, Cookie(t, tm, admin))); err != nil { 587 t.Error(err) 588 } 589 590 // then get user enrollments with group ID 591 wantEnrollment1, err := db.GetEnrollmentByCourseAndUser(course.ID, user1.ID) 592 if err != nil { 593 t.Fatal(err) 594 } 595 wantEnrollment2, err := db.GetEnrollmentByCourseAndUser(course.ID, user2.ID) 596 if err != nil { 597 t.Fatal(err) 598 } 599 600 // delete the group 601 if _, err = client.DeleteGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{ 602 CourseID: course.ID, 603 GroupID: createdGroup.Msg.ID, 604 }, Cookie(t, tm, admin))); err != nil { 605 t.Error(err) 606 } 607 608 // get updated enrollments of group members 609 gotEnrollment1, err := db.GetEnrollmentByCourseAndUser(course.ID, user1.ID) 610 if err != nil { 611 t.Fatal(err) 612 } 613 gotEnrollment2, err := db.GetEnrollmentByCourseAndUser(course.ID, user2.ID) 614 if err != nil { 615 t.Fatal(err) 616 } 617 618 // now nullify manually group ID for original enrollments 619 wantEnrollment1.GroupID = 0 620 wantEnrollment2.GroupID = 0 621 622 // then check that new enrollments have group IDs nullified automatically 623 if diff := cmp.Diff(wantEnrollment1, gotEnrollment1, protocmp.Transform()); diff != "" { 624 t.Errorf("DeleteGroup() mismatch (-wantEnrollment1 +gotEnrollment1):\n%s", diff) 625 } 626 if diff := cmp.Diff(wantEnrollment2, gotEnrollment2, protocmp.Transform()); diff != "" { 627 t.Errorf("DeleteGroup() mismatch (-wantEnrollment2 +gotEnrollment2):\n%s", diff) 628 } 629 } 630 631 func TestGetGroups(t *testing.T) { 632 db, cleanup := qtest.TestDB(t) 633 defer cleanup() 634 635 client, tm, _ := MockClientWithUser(t, db) 636 637 var users []*qf.User 638 for i := 0; i < 10; i++ { 639 user := qtest.CreateFakeUser(t, db) 640 users = append(users, user) 641 } 642 admin := users[0] 643 644 // admin will be enrolled as teacher because of course creation below 645 course := qtest.MockCourses[1] 646 err := db.CreateCourse(admin.ID, course) 647 if err != nil { 648 t.Fatal(err) 649 } 650 651 // enroll all users in course 652 for _, user := range users[1:] { 653 qtest.EnrollStudent(t, db, user, course) 654 } 655 // place some students in groups 656 // current user must be in the group being created 657 ctx := context.Background() 658 group1, err := client.CreateGroup(ctx, qtest.RequestWithCookie(&qf.Group{ 659 Name: "Group1", 660 CourseID: course.ID, 661 Users: []*qf.User{users[1], users[2]}, 662 }, Cookie(t, tm, users[2]))) 663 if err != nil { 664 t.Error(err) 665 } 666 group2, err := client.CreateGroup(ctx, qtest.RequestWithCookie(&qf.Group{ 667 Name: "Group2", 668 CourseID: course.ID, 669 Users: []*qf.User{users[4], users[5]}, 670 }, Cookie(t, tm, users[5]))) 671 if err != nil { 672 t.Error(err) 673 } 674 wantGroups := &qf.Groups{Groups: []*qf.Group{group1.Msg, group2.Msg}} 675 for _, grp := range wantGroups.Groups { 676 for _, grpEnrol := range grp.Enrollments { 677 grpEnrol.UsedSlipDays = []*qf.UsedSlipDays{} 678 } 679 } 680 681 // get groups from the database; current user is admin, which is also teacher 682 gotGroups, err := client.GetGroupsByCourse(ctx, qtest.RequestWithCookie(&qf.CourseRequest{ 683 CourseID: course.ID, 684 }, Cookie(t, tm, admin))) 685 if err != nil { 686 t.Error(err) 687 } 688 689 // check that the method returns expected groups 690 if diff := cmp.Diff(wantGroups, gotGroups.Msg, protocmp.Transform()); diff != "" { 691 t.Errorf("GetGroupsByCourse() mismatch (-wantGroups +gotGroups):\n%s", diff) 692 } 693 }