From 1bf3e3e4c2fbef83fc3b977ff35d170cb41c4646 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sat, 24 Oct 2026 15:26:30 -0700 Subject: [PATCH 01/14] Allow student accounts without birthdays Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../impl/StudentUserDetails.java | 2 +- .../V2__make_student_birthday_nullable.sql | 1 + .../impl/HibernateUserDetailsDaoTest.java | 39 +++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/db/migration/V2__make_student_birthday_nullable.sql diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java index f7cc9a53f..01395e46e 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java @@ -104,7 +104,7 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable @Setter private Gender gender; - @Column(name = StudentUserDetails.COLUMN_NAME_BIRTHDAY, nullable = false) + @Column(name = StudentUserDetails.COLUMN_NAME_BIRTHDAY, nullable = true) @Getter @Setter private Date birthday; diff --git a/src/main/resources/db/migration/V2__make_student_birthday_nullable.sql b/src/main/resources/db/migration/V2__make_student_birthday_nullable.sql new file mode 100644 index 000000000..240da7e0c --- /dev/null +++ b/src/main/resources/db/migration/V2__make_student_birthday_nullable.sql @@ -0,0 +1 @@ +ALTER TABLE student_user_details MODIFY COLUMN birthday datetime NULL; diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java index 566edb272..edf5ee99c 100644 --- a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java +++ b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java @@ -19,6 +19,7 @@ import static org.junit.jupiter.api.Assertions.*; +import java.util.Date; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -28,6 +29,7 @@ import org.wise.portal.domain.authentication.Gender; import org.wise.portal.domain.authentication.Schoollevel; import org.wise.portal.domain.authentication.impl.PersistentUserDetails; +import org.wise.portal.domain.authentication.impl.StudentUserDetails; import org.wise.portal.junit.AbstractTransactionalDbTests; /** @@ -68,6 +70,43 @@ public void retrieveByName_WithExistingStudentName_ShouldReturnUser() { PersistentUserDetails userDetails = userDetailsDao.retrieveByName("SpongebobS0101"); assertNotNull(userDetails); assertEquals("SpongebobS0101", userDetails.getUsername()); + assertNotNull(((StudentUserDetails) userDetails).getBirthday()); + } + + @Test + public void retrieveByName_WithStudentWithoutBirthday_ShouldReturnUser() { + StudentUserDetails studentUserDetails = new StudentUserDetails(); + studentUserDetails.setUsername("NoBirthdayStudent"); + studentUserDetails.setPassword("password"); + studentUserDetails.setFirstname("No"); + studentUserDetails.setLastname("Birthday"); + studentUserDetails.setGender(Gender.MALE); + studentUserDetails.setSignupdate(new Date()); + studentUserDetails.setNumberOfLogins(0); + + userDetailsDao.save(studentUserDetails); + flush(); + sessionFactory.getCurrentSession().clear(); + + StudentUserDetails reloadedStudentUserDetails = + (StudentUserDetails) userDetailsDao.retrieveByName("NoBirthdayStudent"); + + assertNotNull(reloadedStudentUserDetails); + assertNull(reloadedStudentUserDetails.getBirthday()); + } + + @Test + public void retrieveByName_WithStudentBirthday_ShouldReturnBirthdayUnchanged() { + StudentUserDetails studentUserDetails = + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS0101"); + Date birthdayBeforeReload = studentUserDetails.getBirthday(); + flush(); + sessionFactory.getCurrentSession().clear(); + + StudentUserDetails reloadedStudentUserDetails = + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS0101"); + + assertEquals(birthdayBeforeReload, reloadedStudentUserDetails.getBirthday()); } @Test From 5e2ac58b56de336e4b827b45a7798c2d71a984b5 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sat, 24 Oct 2026 15:47:42 -0700 Subject: [PATCH 02/14] Generate student usernames from names only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../impl/StudentUserDetails.java | 17 +--------- .../wise/portal/dao/WISEHibernateTest.java | 8 ++--- .../HibernateAchievementDaoTest.java | 4 +-- .../HibernateStudentAttendanceDaoTest.java | 4 +-- .../impl/HibernateUserDetailsDaoTest.java | 34 ++++++++++++++----- .../impl/HibernateNotificationDaoTest.java | 4 +-- .../dao/user/impl/HibernateUserDaoTest.java | 16 ++++----- .../dao/work/impl/HibernateEventDaoTest.java | 4 +-- .../impl/HibernateNotebookItemDaoTest.java | 4 +-- .../impl/HibernateStudentAssetDaoTest.java | 4 +-- .../impl/HibernateWorkgroupDaoTest.java | 4 +-- .../service/impl/UserServiceImplTest.java | 28 ++++++++++++--- 12 files changed, 76 insertions(+), 55 deletions(-) diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java index 01395e46e..4ac3aff80 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java @@ -131,22 +131,7 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable public String getCoreUsername() { String firstname = getFirstname().replaceAll("[\\s-]+", ""); String lastnameInitial = getLastname().substring(0, 1); - - Calendar birthday = Calendar.getInstance(); - birthday.setTime(this.birthday); - - int birthmonth = birthday.get(Calendar.MONTH) + 1; // month is 0-based - int birthdate = birthday.get(Calendar.DATE); - String birthmonthString = String.valueOf(birthmonth); - if (birthmonth <= 9) { - birthmonthString = "0" + birthmonthString; - } - String birthdateString = String.valueOf(birthdate); - if (birthdate <= 9) { - birthdateString = "0" + birthdateString; - } - - return firstname + lastnameInitial + birthmonthString + birthdateString; + return firstname + lastnameInitial; } public String[] getUsernameSuffixes() { diff --git a/src/test/java/org/wise/portal/dao/WISEHibernateTest.java b/src/test/java/org/wise/portal/dao/WISEHibernateTest.java index 6f7385b2e..4e4470761 100644 --- a/src/test/java/org/wise/portal/dao/WISEHibernateTest.java +++ b/src/test/java/org/wise/portal/dao/WISEHibernateTest.java @@ -63,11 +63,11 @@ public abstract class WISEHibernateTest extends AbstractTransactionalDbTests { @BeforeEach public void setUp() throws Exception { super.setUp(); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); - student2 = createStudentUser("Patrick", "Starr", "PatrickS0101", "rock", 1, 1, Gender.MALE); - student3 = createStudentUser("Sandy", "Cheeks", "SandyC0101", "karate", 1, 1, Gender.FEMALE); - student4 = createStudentUser("Squidward", "Tentacles", "SquidwardT0101", "clarinet", 1, 1, + student2 = createStudentUser("Patrick", "Starr", "PatrickS", "rock", 1, 1, Gender.MALE); + student3 = createStudentUser("Sandy", "Cheeks", "SandyC", "karate", 1, 1, Gender.FEMALE); + student4 = createStudentUser("Squidward", "Tentacles", "SquidwardT", "clarinet", 1, 1, Gender.MALE); runStartTime = Calendar.getInstance().getTime(); teacher1 = createTeacherUser("Mrs", "Puff", "MrsPuff", "Mrs. Puff", "boat", "Bikini Bottom", diff --git a/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java b/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java index c5252f170..9b3391231 100644 --- a/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java +++ b/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java @@ -73,12 +73,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java b/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java index 7ddec8b6f..76624c561 100644 --- a/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java +++ b/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java @@ -77,12 +77,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java index edf5ee99c..81723ae56 100644 --- a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java +++ b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java @@ -49,8 +49,8 @@ public void setUp() throws Exception { createTeacherUser("Mr", "Krabs", "MrKrabs", "Mr. Krabs", "restaurant", "Bikini Bottom", "Water State", "Pacific Ocean", "mrkrabs@bikinibottom.com", "Krusty Krab", Schoollevel.HIGH_SCHOOL, "abcdefghij"); - createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, Gender.MALE); - createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); + createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); } @Test @@ -67,10 +67,28 @@ public void retrieveByName_WithExistingTeacherName_ShouldReturnUser() { @Test public void retrieveByName_WithExistingStudentName_ShouldReturnUser() { - PersistentUserDetails userDetails = userDetailsDao.retrieveByName("SpongebobS0101"); + StudentUserDetails userDetails = + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); assertNotNull(userDetails); - assertEquals("SpongebobS0101", userDetails.getUsername()); - assertNotNull(((StudentUserDetails) userDetails).getBirthday()); + assertEquals("SpongebobS", userDetails.getUsername()); + assertEquals("SpongebobS", userDetails.getCoreUsername()); + assertNotNull(userDetails.getBirthday()); + } + + @Test + public void retrieveByName_WithExistingStudentUsername_ShouldNotRecomputeUsername() { + StudentUserDetails existingStudent = + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); + existingStudent.setUsername("SpongebobS0101"); + flush(); + sessionFactory.getCurrentSession().clear(); + + StudentUserDetails reloadedStudent = + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS0101"); + + assertNotNull(reloadedStudent); + assertEquals("SpongebobS0101", reloadedStudent.getUsername()); + assertEquals("SpongebobS", reloadedStudent.getCoreUsername()); } @Test @@ -98,13 +116,13 @@ public void retrieveByName_WithStudentWithoutBirthday_ShouldReturnUser() { @Test public void retrieveByName_WithStudentBirthday_ShouldReturnBirthdayUnchanged() { StudentUserDetails studentUserDetails = - (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS0101"); + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); Date birthdayBeforeReload = studentUserDetails.getBirthday(); flush(); sessionFactory.getCurrentSession().clear(); StudentUserDetails reloadedStudentUserDetails = - (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS0101"); + (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); assertEquals(birthdayBeforeReload, reloadedStudentUserDetails.getBirthday()); } @@ -145,6 +163,6 @@ public void hasUsername_WithExistingTeacherUsername_ShouldReturnTrue() { @Test public void hasUsername_WithExistingStudentUsername_ShouldReturnTrue() { - assertTrue(userDetailsDao.hasUsername("PatrickS0101")); + assertTrue(userDetailsDao.hasUsername("PatrickS")); } } diff --git a/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java b/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java index 277038f73..4bbcd7674 100644 --- a/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java +++ b/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java @@ -53,12 +53,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java index 54b13c2f5..cab6adc22 100644 --- a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java +++ b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java @@ -52,9 +52,9 @@ public void setUp() throws Exception { teacher2 = createTeacherUser("Mr", "Krabs", "MrKrabs", "Mr. Krabs", "restaurant", "Bikini Bottom", "Water State", "Pacific Ocean", "mrkrabs@bikinibottom.com", "Krusty Krab", Schoollevel.HIGH_SCHOOL, "abcdefghij"); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); - student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); } @Test @@ -72,8 +72,8 @@ public void retrieveAllUsernames_ShouldReturnAllUsernames() { assertTrue(usernames.contains("preview")); assertTrue(usernames.contains("MrsPuff")); assertTrue(usernames.contains("MrKrabs")); - assertTrue(usernames.contains("SpongebobS0101")); - assertTrue(usernames.contains("PatrickS0101")); + assertTrue(usernames.contains("SpongebobS")); + assertTrue(usernames.contains("PatrickS")); } @Test @@ -85,9 +85,9 @@ public void retrieveByUsername_WithExistingTeacherUsername_ShouldReturnTeacher() @Test public void retrieveByUsername_WithExistingStudentUsername_ShouldReturnStudent() { - User user = userDao.retrieveByUsername("SpongebobS0101"); + User user = userDao.retrieveByUsername("SpongebobS"); UserDetails userDetails = user.getUserDetails(); - assertEquals("SpongebobS0101", userDetails.getUsername()); + assertEquals("SpongebobS", userDetails.getUsername()); } @Test @@ -299,13 +299,13 @@ public void retrieveStudentsByLastName_WithExistingLastName_ShouldReturnUser() { @Test public void retrieveStudentByUsername_WithNonExistingUsername_ShouldNotReturnAnyUser() { - User user = userDao.retrieveStudentByUsername("BillD0101"); + User user = userDao.retrieveStudentByUsername("BillD"); assertNull(user); } @Test public void retrieveStudentsByUsername_WithExistingUsername_ShouldReturnUser() { - User user = userDao.retrieveStudentByUsername("SpongebobS0101"); + User user = userDao.retrieveStudentByUsername("SpongebobS"); assertEquals(student1.getId(), user.getId()); } diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java index c56785ed7..f36722b57 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java @@ -66,9 +66,9 @@ public void setUp() throws Exception { teacher1 = createTeacherUser("Mrs", "Puff", "MrsPuff", "Mrs. Puff", "boat", "Bikini Bottom", "Water State", "Pacific Ocean", "mrspuff@bikinibottom.com", "Boating School", Schoollevel.COLLEGE, "1234567890"); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); - student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Long id = getNextAvailableProjectId(); String projectName = "How to be a Fry Cook"; Date startTime = Calendar.getInstance().getTime(); diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java index 9110b9404..0f00e39f2 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java @@ -74,12 +74,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java index 82ea7d0b9..240119316 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java @@ -52,12 +52,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java b/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java index af7474726..0d2ebe8e0 100644 --- a/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java +++ b/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java @@ -74,12 +74,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS0101", "burger", 1, 1, + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); Set members1 = new HashSet(); members1.add(student1); createWorkgroup(members1, run, period1); - student2 = createStudentUser("Patrick", "Star", "PatrickS0101", "rock", 1, 1, Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); } @Test diff --git a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java index 6de32c054..7122bacda 100644 --- a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java +++ b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java @@ -147,32 +147,50 @@ public void setupCreateTest() { @Test public void createUser_ValidStudentUser_ShouldCreateStudentUser() throws Exception { + studentUserDetails.setFirstname(" Bil-ly "); + studentUserDetails.setLastname(" Bob "); expectStudentAuthorityLookup(); - expect(userDetailsDao.hasUsername("BillyB1219")).andReturn(false); + expect(userDetailsDao.hasUsername("BillyB")).andReturn(false); replay(userDetailsDao); expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); replay(passwordEncoder); userService.createUser(studentUserDetails); verify(grantedAuthorityDao); verify(userDetailsDao); - assertEquals("BillyB1219", studentUserDetails.getUsername()); + assertEquals("BillyB", studentUserDetails.getUsername()); assertEquals(ENCODED_PASSWORD, studentUserDetails.getPassword()); assertUserHasStudentAuthorities(); } + @Test + public void createUser_StudentWithoutBirthday_ShouldCreateNameOnlyUsername() throws Exception { + studentUserDetails.setBirthday(null); + expectStudentAuthorityLookup(); + expect(userDetailsDao.hasUsername("BillyB")).andReturn(false); + replay(userDetailsDao); + expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); + replay(passwordEncoder); + + userService.createUser(studentUserDetails); + + verify(grantedAuthorityDao); + verify(userDetailsDao); + assertEquals("BillyB", studentUserDetails.getUsername()); + } + @Test public void createUser_DuplicateStudentUsername_ShouldAppendSuffixToStudentUsername() throws Exception { expectStudentAuthorityLookup(); - expect(userDetailsDao.hasUsername("BillyB1219")).andReturn(true); - expect(userDetailsDao.hasUsername("BillyB1219a")).andReturn(false); + expect(userDetailsDao.hasUsername("BillyB")).andReturn(true); + expect(userDetailsDao.hasUsername("BillyBa")).andReturn(false); replay(userDetailsDao); expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); replay(passwordEncoder); userService.createUser(studentUserDetails); verify(grantedAuthorityDao); verify(userDetailsDao); - assertEquals("BillyB1219a", studentUserDetails.getUsername()); + assertEquals("BillyBa", studentUserDetails.getUsername()); assertEquals(ENCODED_PASSWORD, studentUserDetails.getPassword()); assertUserHasStudentAuthorities(); } From 1393633bed448c1b243f39b9214444a59e98dbf4 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sat, 24 Oct 2026 16:17:50 -0700 Subject: [PATCH 03/14] Use numeric student username suffixes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../authentication/MutableUserDetails.java | 6 ---- .../impl/PersistentUserDetails.java | 6 ---- .../impl/StudentUserDetails.java | 35 ++++--------------- .../impl/TeacherUserDetails.java | 5 --- .../service/impl/UserServiceImplTest.java | 21 +++++++++-- 5 files changed, 26 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/wise/portal/domain/authentication/MutableUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/MutableUserDetails.java index f34b7eb51..224e70f49 100644 --- a/src/main/java/org/wise/portal/domain/authentication/MutableUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/MutableUserDetails.java @@ -186,12 +186,6 @@ public interface MutableUserDetails extends UserDetails, Persistable { */ String getCoreUsername(); - /** - * In case username is not unique, append an item from the list of suffices. - * @return array of suffices to add to end of username to make it unique - */ - String[] getUsernameSuffixes(); - /** * Get the next username suffix * @param currentUsernameSuffix diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/PersistentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/PersistentUserDetails.java index 026290d48..46a014958 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/PersistentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/PersistentUserDetails.java @@ -376,12 +376,6 @@ public String getCoreUsername() { return null; } - @Override - public String[] getUsernameSuffixes() { - // TODO Auto-generated method stub - return null; - } - @Override public String getNextUsernameSuffix(String currentUsernameSuffix) { // TODO Auto-generated method stub diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java index 4ac3aff80..68e5a4ab7 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java @@ -134,41 +134,20 @@ public String getCoreUsername() { return firstname + lastnameInitial; } - public String[] getUsernameSuffixes() { - return new String[] { "", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", - "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; - } - /** - * Get the next username suffix. For students the suffix is just an alphabet letter. If we reach - * "z" we will then move on to "aa", if we reach "az" we will then move on to "aaa", etc. e.g. "x" - * "y" "z" "aa" "ab" + * Get the next numeric username suffix for students. * - * @param currentUsernameSuffix - * the current suffix - * @see MutableUserDetails#getNextUsernameSuffix(String) - * @return the next username suffix which will be the next letter in the alphabet + * @param currentUsernameSuffix the current suffix + * @return the next suffix, starting with "2" after the unsuffixed username */ public String getNextUsernameSuffix(String currentUsernameSuffix) { - String nextUsernameSuffix = ""; if (currentUsernameSuffix == null) { - nextUsernameSuffix = ""; - } else if ("".equals(currentUsernameSuffix)) { - nextUsernameSuffix = "a"; + return ""; + } else if (currentUsernameSuffix.isEmpty()) { + return "2"; } else { - if (currentUsernameSuffix.length() > 0) { - char lastChar = currentUsernameSuffix.charAt(currentUsernameSuffix.length() - 1); - if (lastChar == 'z') { - String beginningCurrentUsernameSuffix = currentUsernameSuffix.substring(0, - currentUsernameSuffix.length() - 1); - nextUsernameSuffix = beginningCurrentUsernameSuffix + "aa"; - } else { - nextUsernameSuffix = currentUsernameSuffix.substring(0, - currentUsernameSuffix.length() - 1) + (char) (lastChar + 1); - } - } + return String.valueOf(Integer.parseInt(currentUsernameSuffix) + 1); } - return nextUsernameSuffix; } public Date getLastLoginTime() { diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/TeacherUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/TeacherUserDetails.java index a03bc24ba..db0447f96 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/TeacherUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/TeacherUserDetails.java @@ -170,11 +170,6 @@ public String getCoreUsername() { return (firstname + lastname).replaceAll("[\\s-]+", ""); } - public String[] getUsernameSuffixes() { - return new String[] { "", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", - "14", "15", "16" }; - } - /** * Get the next username suffix. For teachers the suffix is just an integer that we will increment * diff --git a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java index 7122bacda..5b5cf7fd1 100644 --- a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java +++ b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java @@ -183,18 +183,35 @@ public void createUser_DuplicateStudentUsername_ShouldAppendSuffixToStudentUsern throws Exception { expectStudentAuthorityLookup(); expect(userDetailsDao.hasUsername("BillyB")).andReturn(true); - expect(userDetailsDao.hasUsername("BillyBa")).andReturn(false); + expect(userDetailsDao.hasUsername("BillyB2")).andReturn(false); replay(userDetailsDao); expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); replay(passwordEncoder); userService.createUser(studentUserDetails); verify(grantedAuthorityDao); verify(userDetailsDao); - assertEquals("BillyBa", studentUserDetails.getUsername()); + assertEquals("BillyB2", studentUserDetails.getUsername()); assertEquals(ENCODED_PASSWORD, studentUserDetails.getPassword()); assertUserHasStudentAuthorities(); } + @Test + public void createUser_RepeatedStudentUsername_ShouldIncrementNumericSuffix() throws Exception { + expectStudentAuthorityLookup(); + expect(userDetailsDao.hasUsername("BillyB")).andReturn(true); + expect(userDetailsDao.hasUsername("BillyB2")).andReturn(true); + expect(userDetailsDao.hasUsername("BillyB3")).andReturn(false); + replay(userDetailsDao); + expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); + replay(passwordEncoder); + + userService.createUser(studentUserDetails); + + verify(grantedAuthorityDao); + verify(userDetailsDao); + assertEquals("BillyB3", studentUserDetails.getUsername()); + } + @Test public void createUser_ValidTeacherUser_ShouldCreateTeacherUser() throws Exception { expectTeacherAuthorityLookup(); From 1ae11b18a9c3e31e30c40d1cecf65436fb2340fb Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sun, 25 Oct 2026 11:59:37 -0700 Subject: [PATCH 04/14] Remove birthday from student registration Ignore legacy birth fields in student account registration and add coverage for password, Google, and Microsoft flows without birthdays. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../student/StudentAPIController.java | 10 --- .../student/StudentAPIControllerTest.java | 67 +++++++++++++++++-- 2 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentAPIController.java index cf567dc8f..efd28b5ed 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentAPIController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentAPIController.java @@ -306,7 +306,6 @@ ResponseEntity> createStudentAccount( sud.setGender(getGender(studentFields.get("gender"))); sud.setAccountQuestion(studentFields.get("securityQuestion")); sud.setAccountAnswer(studentFields.get("securityQuestionAnswer")); - sud.setBirthday(getBirthDate(studentFields.get("birthMonth"), studentFields.get("birthDay"))); sud.setSignupdate(Calendar.getInstance().getTime()); if (studentFields.containsKey("googleUserId")) { sud.setGoogleUserId(studentFields.get("googleUserId")); @@ -339,15 +338,6 @@ private Gender getGender(String gender) { } } - private Date getBirthDate(String birthMonthStr, String birthDayStr) { - Integer birthMonth = Integer.parseInt(birthMonthStr); - Integer birthDay = Integer.parseInt(birthDayStr); - Calendar birthday = Calendar.getInstance(); - birthday.set(Calendar.MONTH, birthMonth - 1); // month is 0 indexed - birthday.set(Calendar.DATE, birthDay); - return birthday.getTime(); - } - @GetMapping("/register/questions") List> getSecurityQuestions() { List> questions = new ArrayList>(); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java index 31072fd24..74b196dfe 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java @@ -13,6 +13,7 @@ import java.util.Properties; import java.util.Set; +import org.easymock.Capture; import org.easymock.EasyMockExtension; import org.easymock.Mock; import org.easymock.TestSubject; @@ -225,17 +226,77 @@ public void addStudentToRun_ValidRunCodeAndPeriod_AddStudentToRun() } @Test - public void createStudentAccount_WithGoogleUserId_CreateUser() + public void createStudentAccount_WithoutBirthdayWithGoogleUserId_CreateUser() throws DuplicateUsernameException, InvalidNameException { HashMap studentFields = createDefaultStudentFields(); studentFields.put("googleUserId", "123456789"); expect(request.getLocale()).andReturn(Locale.US); replay(request); - expect(userService.createUser(isA(StudentUserDetails.class))).andReturn(student1); + Capture createdDetails = newCapture(); + expect(userService.createUser(capture(createdDetails))).andReturn(student1); replay(userService); ResponseEntity> response = studentAPIController .createStudentAccount(studentFields, request); assertEquals(STUDENT_USERNAME, response.getBody().get("username")); + assertEquals("123456789", createdDetails.getValue().getGoogleUserId()); + assertNull(createdDetails.getValue().getBirthday()); + verify(request); + verify(userService); + } + + @Test + public void createStudentAccount_WithoutBirthdayWithPassword_CreateUser() + throws DuplicateUsernameException, InvalidNameException { + HashMap studentFields = createDefaultStudentFields(); + studentFields.put("password", PasswordServiceImpl.VALID_PASSWORD); + expect(request.getLocale()).andReturn(Locale.US); + replay(request); + Capture createdDetails = newCapture(); + expect(userService.createUser(capture(createdDetails))).andReturn(student1); + replay(userService); + ResponseEntity> response = studentAPIController + .createStudentAccount(studentFields, request); + assertEquals(STUDENT_USERNAME, response.getBody().get("username")); + assertNull(createdDetails.getValue().getBirthday()); + verify(request); + verify(userService); + } + + @Test + public void createStudentAccount_WithoutBirthdayWithMicrosoftUserId_CreateUser() + throws DuplicateUsernameException, InvalidNameException { + HashMap studentFields = createDefaultStudentFields(); + studentFields.put("microsoftUserId", "microsoft-123456789"); + expect(request.getLocale()).andReturn(Locale.US); + replay(request); + Capture createdDetails = newCapture(); + expect(userService.createUser(capture(createdDetails))).andReturn(student1); + replay(userService); + ResponseEntity> response = studentAPIController + .createStudentAccount(studentFields, request); + assertEquals(STUDENT_USERNAME, response.getBody().get("username")); + assertEquals("microsoft-123456789", createdDetails.getValue().getMicrosoftUserId()); + assertNull(createdDetails.getValue().getBirthday()); + verify(request); + verify(userService); + } + + @Test + public void createStudentAccount_WithLegacyBirthdayValues_DoesNotStoreBirthday() + throws DuplicateUsernameException, InvalidNameException { + HashMap studentFields = createDefaultStudentFields(); + studentFields.put("birthMonth", "not-a-month"); + studentFields.put("birthDay", "not-a-day"); + studentFields.put("password", PasswordServiceImpl.VALID_PASSWORD); + expect(request.getLocale()).andReturn(Locale.US); + replay(request); + Capture createdDetails = newCapture(); + expect(userService.createUser(capture(createdDetails))).andReturn(student1); + replay(userService); + ResponseEntity> response = studentAPIController + .createStudentAccount(studentFields, request); + assertEquals(STUDENT_USERNAME, response.getBody().get("username")); + assertNull(createdDetails.getValue().getBirthday()); verify(request); verify(userService); } @@ -255,8 +316,6 @@ private HashMap createDefaultStudentFields() { HashMap studentFields = new HashMap(); studentFields.put("firstName", STUDENT_FIRSTNAME); studentFields.put("lastName", STUDENT_LASTNAME); - studentFields.put("birthMonth", "1"); - studentFields.put("birthDay", "1"); studentFields.put("gender", "MALE"); return studentFields; } From e0d0a45fd03a70c70e8291f30c9b582ad5d36c57 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sun, 25 Oct 2026 12:25:30 -0700 Subject: [PATCH 05/14] Refactor StudentAPIControllerTest --- .../student/StudentAPIControllerTest.java | 60 ++++++------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java index 74b196dfe..b9b4ef060 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java @@ -226,59 +226,30 @@ public void addStudentToRun_ValidRunCodeAndPeriod_AddStudentToRun() } @Test - public void createStudentAccount_WithoutBirthdayWithGoogleUserId_CreateUser() + public void createStudentAccount_WithValidPassword_CreateUser() throws DuplicateUsernameException, InvalidNameException { HashMap studentFields = createDefaultStudentFields(); - studentFields.put("googleUserId", "123456789"); - expect(request.getLocale()).andReturn(Locale.US); - replay(request); - Capture createdDetails = newCapture(); - expect(userService.createUser(capture(createdDetails))).andReturn(student1); - replay(userService); - ResponseEntity> response = studentAPIController - .createStudentAccount(studentFields, request); - assertEquals(STUDENT_USERNAME, response.getBody().get("username")); - assertEquals("123456789", createdDetails.getValue().getGoogleUserId()); - assertNull(createdDetails.getValue().getBirthday()); - verify(request); - verify(userService); + studentFields.put("password", PasswordServiceImpl.VALID_PASSWORD); + StudentUserDetails createdDetails = registerStudentAccount(studentFields); + assertEquals(PasswordServiceImpl.VALID_PASSWORD, createdDetails.getPassword()); } - + @Test - public void createStudentAccount_WithoutBirthdayWithPassword_CreateUser() + public void createStudentAccount_WithGoogleUserId_CreateUser() throws DuplicateUsernameException, InvalidNameException { HashMap studentFields = createDefaultStudentFields(); - studentFields.put("password", PasswordServiceImpl.VALID_PASSWORD); - expect(request.getLocale()).andReturn(Locale.US); - replay(request); - Capture createdDetails = newCapture(); - expect(userService.createUser(capture(createdDetails))).andReturn(student1); - replay(userService); - ResponseEntity> response = studentAPIController - .createStudentAccount(studentFields, request); - assertEquals(STUDENT_USERNAME, response.getBody().get("username")); - assertNull(createdDetails.getValue().getBirthday()); - verify(request); - verify(userService); + studentFields.put("googleUserId", "123456789"); + StudentUserDetails createdDetails = registerStudentAccount(studentFields); + assertEquals("123456789", createdDetails.getGoogleUserId()); } @Test - public void createStudentAccount_WithoutBirthdayWithMicrosoftUserId_CreateUser() + public void createStudentAccount_WithMicrosoftUserId_CreateUser() throws DuplicateUsernameException, InvalidNameException { HashMap studentFields = createDefaultStudentFields(); studentFields.put("microsoftUserId", "microsoft-123456789"); - expect(request.getLocale()).andReturn(Locale.US); - replay(request); - Capture createdDetails = newCapture(); - expect(userService.createUser(capture(createdDetails))).andReturn(student1); - replay(userService); - ResponseEntity> response = studentAPIController - .createStudentAccount(studentFields, request); - assertEquals(STUDENT_USERNAME, response.getBody().get("username")); - assertEquals("microsoft-123456789", createdDetails.getValue().getMicrosoftUserId()); - assertNull(createdDetails.getValue().getBirthday()); - verify(request); - verify(userService); + StudentUserDetails createdDetails = registerStudentAccount(studentFields); + assertEquals("microsoft-123456789", createdDetails.getMicrosoftUserId()); } @Test @@ -288,6 +259,12 @@ public void createStudentAccount_WithLegacyBirthdayValues_DoesNotStoreBirthday() studentFields.put("birthMonth", "not-a-month"); studentFields.put("birthDay", "not-a-day"); studentFields.put("password", PasswordServiceImpl.VALID_PASSWORD); + StudentUserDetails createdDetails = registerStudentAccount(studentFields); + assertEquals(PasswordServiceImpl.VALID_PASSWORD, createdDetails.getPassword()); + } + + private StudentUserDetails registerStudentAccount(Map studentFields) + throws DuplicateUsernameException, InvalidNameException { expect(request.getLocale()).andReturn(Locale.US); replay(request); Capture createdDetails = newCapture(); @@ -299,6 +276,7 @@ public void createStudentAccount_WithLegacyBirthdayValues_DoesNotStoreBirthday() assertNull(createdDetails.getValue().getBirthday()); verify(request); verify(userService); + return createdDetails.getValue(); } @Test From 6200dd617e8d11e70fe128f7d8d788cd4fec6840 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sun, 25 Oct 2026 12:33:10 -0700 Subject: [PATCH 06/14] Remove birthday placeholder from survey students Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../web/controllers/survey/SurveyAPIController.java | 1 - .../controllers/survey/SurveyAPIControllerTest.java | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIController.java index 409485a74..6b9f7c780 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIController.java @@ -134,7 +134,6 @@ private User createNewStudentAccount(Locale locale, String password) StudentUserDetails sud = new StudentUserDetails(); sud.setFirstname("survey_student_" + RandomStringUtils.randomAlphanumeric(10)); sud.setLastname(RandomStringUtils.randomAlphanumeric(10)); - sud.setBirthday(new Date()); sud.setPassword(password); sud.setGender(Gender.UNSPECIFIED); sud.setEmailAddress("null@null.com"); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java index 030f93808..f46c065ba 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java @@ -1,10 +1,13 @@ package org.wise.portal.presentation.web.controllers.survey; +import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.isA; +import static org.easymock.EasyMock.newCapture; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; +import static org.junit.jupiter.api.Assertions.assertNull; import java.util.ArrayList; import java.util.Date; @@ -17,6 +20,7 @@ import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpServletRequest; +import org.easymock.Capture; import org.easymock.EasyMockExtension; import org.easymock.Mock; import org.easymock.TestSubject; @@ -195,7 +199,8 @@ public void launchSurveyRun_NoIssues_RedirectUnit() throws Exception { expect(runService.retrieveRunByRuncode("dog1234")).andReturn(run); replay(runService); studentUser.setUserDetails(studentUserDetails); - expect(userService.createUser(studentUserDetails)).andReturn(studentUser); + Capture createdStudentDetails = newCapture(); + expect(userService.createUser(capture(createdStudentDetails))).andReturn(studentUser); replay(userService); SecurityContextHolder.setContext(getSecurityContext("anonymousUser", "ROLE_ANONYMOUS")); expect(workgroupService.getWorkgroupsForRun(run)).andReturn(new ArrayList()); @@ -209,6 +214,7 @@ public void launchSurveyRun_NoIssues_RedirectUnit() throws Exception { expectLastCall(); replay(studentService); surveyAPIController.launchSurveyRun("dog1234-1", httpServletResponse, httpServletRequest); - verify(httpServletResponse, runService, workgroupService, studentService); + verify(httpServletResponse, runService, userService, workgroupService, studentService); + assertNull(createdStudentDetails.getValue().getBirthday()); } } From 41674007716125a9264cf88580218a05a405e9aa Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sun, 25 Oct 2026 13:17:09 -0700 Subject: [PATCH 07/14] Update batch student CSV format Reject legacy birthday columns before creating accounts, and import students without birthdays using the current layout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../BatchCreateUserAccountsController.java | 145 +++++++++++------- .../admin/account/batchcreateuseraccounts.jsp | 6 + .../WISE_BatchCreateUserAccounts_Sample.csv | 6 +- ...BatchCreateUserAccountsControllerTest.java | 93 +++++++++++ 4 files changed, 193 insertions(+), 57 deletions(-) create mode 100644 src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsController.java b/src/main/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsController.java index 16810ec51..e1a42b8ca 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsController.java @@ -26,8 +26,11 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Calendar; +import java.util.List; +import java.util.Locale; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.annotation.Secured; @@ -62,6 +65,9 @@ @RequestMapping("/admin/account/batchcreateuseraccounts.html") public class BatchCreateUserAccountsController { + private static final String CSV_FORMAT_ERROR = + "This CSV file does not match the updated format. Please download and use the updated template."; + @Autowired private UserService userService; @@ -72,72 +78,99 @@ public class BatchCreateUserAccountsController { protected ModelAndView onSubmit( @ModelAttribute("csvFile") BatchCreateUserAccountsUpload csvUpload, BindingResult result) throws Exception { - ArrayList newUsernames = new ArrayList(); - MultipartFile csvFile = csvUpload.getFile(); - InputStreamReader inputStreamReader = new InputStreamReader(csvFile.getInputStream()); + List studentRows = new ArrayList(); Gender[] genderArray = {Gender.MALE,Gender.FEMALE,Gender.UNSPECIFIED}; AccountQuestion[] accountQuestionArray = { AccountQuestion.QUESTION_FOUR, AccountQuestion.QUESTION_TWO, AccountQuestion.QUESTION_THREE }; - BufferedReader br = null; - String line = ""; - String cvsSplitBy = ","; + if (!readStudentRows(csvUpload.getFile(), studentRows, genderArray, accountQuestionArray)) { + return csvFormatError(); + } + ArrayList newUsernames = + createStudentAccounts(studentRows, genderArray, accountQuestionArray); + ModelAndView modelAndView = new ModelAndView("admin/account/batchcreateuseraccounts"); + modelAndView.addObject("msg", "Batch create user accounts complete!"); + modelAndView.addObject("newUsernames", newUsernames); + return modelAndView; + } - try { - br = new BufferedReader(inputStreamReader); + private boolean readStudentRows(MultipartFile csvFile, List studentRows, + Gender[] genderArray, AccountQuestion[] accountQuestionArray) throws IOException { + try (BufferedReader br = new BufferedReader( + new InputStreamReader(csvFile.getInputStream(), StandardCharsets.UTF_8))) { + String line; while ((line = br.readLine()) != null) { - String[] userInfo = line.split(cvsSplitBy); - if ("Firstname".equals(userInfo[0]) && "Lastname".equals(userInfo[1])) { - continue; - } - String firstname = userInfo[0]; - String lastname = userInfo[1]; - Gender gender = genderArray[Integer.valueOf(userInfo[2])]; - String password = userInfo[5]; - AccountQuestion accountQuestion = accountQuestionArray[Integer.valueOf(userInfo[6])]; - String accountAnswer = userInfo[7]; - StudentUserDetails studentUserDetails = new StudentUserDetails(); - studentUserDetails.setFirstname(firstname); - studentUserDetails.setLastname(lastname); - studentUserDetails.setGender(gender); - studentUserDetails.setPassword(password); - studentUserDetails.setAccountQuestion(accountQuestion.toString()); - studentUserDetails.setAccountAnswer(accountAnswer); - studentUserDetails.setSignupdate(Calendar.getInstance().getTime()); - int birthmonth = Integer.parseInt(userInfo[3]); - int birthdate = Integer.parseInt(userInfo[4]); - Calendar birthday = Calendar.getInstance(); - birthday.set(Calendar.MONTH, birthmonth - 1); // month is 0-based - birthday.set(Calendar.DATE, birthdate); - studentUserDetails.setBirthday(birthday.getTime()); - User user = userService.createUser(studentUserDetails); - String accessCode = userInfo[8]; - String period = userInfo[9]; - Projectcode projectcode = new Projectcode(accessCode,period); - studentService.addStudentToRun(user, projectcode); - newUsernames.add(studentUserDetails.getUsername()); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if (inputStreamReader != null) { - try { - inputStreamReader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - if (br != null) { - try { - br.close(); - } catch (IOException e) { - e.printStackTrace(); + if (!line.isBlank()) { + String[] userInfo = line.split(",", -1); + boolean headerRow = isHeaderRow(userInfo); + boolean invalidRow = headerRow + ? line.toLowerCase(Locale.ROOT).contains("birthday") + : isInvalidRow(genderArray, accountQuestionArray, userInfo); + if (invalidRow) { + return false; + } else if (!headerRow) { + studentRows.add(userInfo); + } } } } + return true; + } + + private boolean isInvalidRow(Gender[] genderArray, AccountQuestion[] accountQuestionArray, + String[] userInfo) { + return userInfo.length != 8 || !hasValidAccountIndexes(userInfo, genderArray, + accountQuestionArray); + } + + private boolean isHeaderRow(String[] userInfo) { + return userInfo.length >= 2 && "Firstname".equals(userInfo[0]) + && "Lastname".equals(userInfo[1]); + } + + private ArrayList createStudentAccounts(List studentRows, + Gender[] genderArray, AccountQuestion[] accountQuestionArray) throws Exception { + ArrayList newUsernames = new ArrayList(); + for (String[] userInfo : studentRows) { + String firstname = userInfo[0]; + String lastname = userInfo[1]; + Gender gender = genderArray[Integer.valueOf(userInfo[2])]; + String password = userInfo[3]; + AccountQuestion accountQuestion = accountQuestionArray[Integer.valueOf(userInfo[4])]; + String accountAnswer = userInfo[5]; + StudentUserDetails studentUserDetails = new StudentUserDetails(); + studentUserDetails.setFirstname(firstname); + studentUserDetails.setLastname(lastname); + studentUserDetails.setGender(gender); + studentUserDetails.setPassword(password); + studentUserDetails.setAccountQuestion(accountQuestion.toString()); + studentUserDetails.setAccountAnswer(accountAnswer); + studentUserDetails.setSignupdate(Calendar.getInstance().getTime()); + User user = userService.createUser(studentUserDetails); + String accessCode = userInfo[6]; + String period = userInfo[7]; + Projectcode projectcode = new Projectcode(accessCode, period); + studentService.addStudentToRun(user, projectcode); + newUsernames.add(studentUserDetails.getUsername()); + } + return newUsernames; + } + + private boolean hasValidAccountIndexes(String[] userInfo, Gender[] genderArray, + AccountQuestion[] accountQuestionArray) { + try { + int genderIndex = Integer.parseInt(userInfo[2]); + int accountQuestionIndex = Integer.parseInt(userInfo[4]); + return genderIndex >= 0 && genderIndex < genderArray.length + && accountQuestionIndex >= 0 && accountQuestionIndex < accountQuestionArray.length; + } catch (NumberFormatException e) { + return false; + } + } + + private ModelAndView csvFormatError() { ModelAndView modelAndView = new ModelAndView("admin/account/batchcreateuseraccounts"); - modelAndView.addObject("msg", "Batch create user accounts complete!"); - modelAndView.addObject("newUsernames", newUsernames); + modelAndView.addObject("error", CSV_FORMAT_ERROR); return modelAndView; } diff --git a/src/main/webapp/portal/admin/account/batchcreateuseraccounts.jsp b/src/main/webapp/portal/admin/account/batchcreateuseraccounts.jsp index 301491bf3..8e6cb9c51 100644 --- a/src/main/webapp/portal/admin/account/batchcreateuseraccounts.jsp +++ b/src/main/webapp/portal/admin/account/batchcreateuseraccounts.jsp @@ -34,6 +34,12 @@

+ +
+ +
+
+
${msg}

diff --git a/src/main/webapp/portal/pages/resources/WISE_BatchCreateUserAccounts_Sample.csv b/src/main/webapp/portal/pages/resources/WISE_BatchCreateUserAccounts_Sample.csv index ec46522a2..f1693e764 100644 --- a/src/main/webapp/portal/pages/resources/WISE_BatchCreateUserAccounts_Sample.csv +++ b/src/main/webapp/portal/pages/resources/WISE_BatchCreateUserAccounts_Sample.csv @@ -1 +1,5 @@ -Firstname,Lastname,"Gender (0=M,1=F,2=Unspecified)",Birthday (Month),Birthday (Day),Password,"Security Question Index (0=favorite animal,1=mother's first name, or 2=grandmother's first name)",Security Question Answer,Access Code,Class Period John,Lennon,0,10,9,test,0,koala,Mole727,1 Paul,McCartney,0,6,18,test,0,koala,Mole727,1 George,Harrison,0,2,25,test,0,koala,Mole727,1 Ringo,Starr,0,7,7,test,0,koala,Mole727,1 \ No newline at end of file +Firstname,Lastname,"Gender (0=M,1=F,2=Unspecified)",Password,"Security Question Index (0=favorite animal,1=mother's first name, or 2=grandmother's first name)",Security Question Answer,Access Code,Class Period +John,Lennon,0,test,0,koala,Mole727,1 +Paul,McCartney,0,test,0,koala,Mole727,1 +George,Harrison,0,test,0,koala,Mole727,1 +Ringo,Starr,0,test,0,koala,Mole727,1 diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java new file mode 100644 index 000000000..4f29e33d2 --- /dev/null +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java @@ -0,0 +1,93 @@ +package org.wise.portal.presentation.web.controllers.admin; + +import static org.easymock.EasyMock.*; +import static org.junit.jupiter.api.Assertions.*; + +import java.nio.charset.StandardCharsets; +import java.util.List; + +import org.easymock.Capture; +import org.easymock.EasyMockExtension; +import org.easymock.Mock; +import org.easymock.TestSubject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.web.servlet.ModelAndView; +import org.wise.portal.domain.AccountQuestion; +import org.wise.portal.domain.authentication.Gender; +import org.wise.portal.domain.authentication.impl.StudentUserDetails; +import org.wise.portal.domain.project.impl.Projectcode; +import org.wise.portal.domain.user.BatchCreateUserAccountsUpload; +import org.wise.portal.domain.user.User; +import org.wise.portal.domain.user.impl.UserImpl; +import org.wise.portal.service.student.StudentService; +import org.wise.portal.service.user.UserService; + +@ExtendWith(EasyMockExtension.class) +public class BatchCreateUserAccountsControllerTest { + + @TestSubject + private BatchCreateUserAccountsController controller = new BatchCreateUserAccountsController(); + + @Mock + private UserService userService; + + @Mock + private StudentService studentService; + + @Test + public void onSubmit_WithUpdatedCsvLayout_CreatesNameBasedStudentAndAddsToRun() + throws Exception { + String csv = "Firstname,Lastname,Gender,Password,Security Question Index," + + "Security Question Answer,Access Code,Class Period\n" + + "John,Lennon,0,test,0,koala,Mole727,1\n"; + BatchCreateUserAccountsUpload upload = upload(csv); + User createdUser = new UserImpl(); + Capture studentDetails = Capture.newInstance(); + expect(userService.createUser(capture(studentDetails))).andAnswer(() -> { + ((StudentUserDetails) getCurrentArguments()[0]).setUsername("JohnL"); + return createdUser; + }); + studentService.addStudentToRun(createdUser, new Projectcode("Mole727", "1")); + expectLastCall(); + replay(userService, studentService); + + ModelAndView response = controller.onSubmit(upload, null); + + assertEquals("admin/account/batchcreateuseraccounts", response.getViewName()); + assertNull(studentDetails.getValue().getBirthday()); + assertEquals("John", studentDetails.getValue().getFirstname()); + assertEquals("Lennon", studentDetails.getValue().getLastname()); + assertEquals("JohnL", studentDetails.getValue().getCoreUsername()); + assertEquals(Gender.MALE, studentDetails.getValue().getGender()); + assertEquals("test", studentDetails.getValue().getPassword()); + assertEquals(AccountQuestion.QUESTION_FOUR.toString(), + studentDetails.getValue().getAccountQuestion()); + assertEquals("koala", studentDetails.getValue().getAccountAnswer()); + assertEquals(List.of("JohnL"), response.getModel().get("newUsernames")); + verify(userService, studentService); + } + + @Test + public void onSubmit_WithLegacyBirthdayColumns_RejectsBeforeCreatingAccounts() + throws Exception { + String csv = "Firstname,Lastname,Gender,Birthday (Month),Birthday (Day),Password," + + "Security Question Index,Security Question Answer,Access Code,Class Period\n" + + "John,Lennon,0,10,9,test,0,koala,Mole727,1\n"; + replay(userService, studentService); + + ModelAndView response = controller.onSubmit(upload(csv), null); + + assertEquals("admin/account/batchcreateuseraccounts", response.getViewName()); + assertTrue(((String) response.getModel().get("error")).contains("updated template")); + verify(userService, studentService); + } + + private BatchCreateUserAccountsUpload upload(String csv) { + BatchCreateUserAccountsUpload upload = new BatchCreateUserAccountsUpload(); + upload.setFile(new MockMultipartFile("file", "students.csv", "text/csv", + csv.getBytes(StandardCharsets.UTF_8))); + return upload; + } +} From 54857b4fb10cebd8e361809b80abb1c2ba82cdc0 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Sun, 25 Oct 2026 14:44:47 -0700 Subject: [PATCH 08/14] Find student usernames by name only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../org/wise/portal/dao/user/UserDao.java | 3 +- .../dao/user/impl/HibernateUserDao.java | 7 +--- .../StudentForgotAccountAPIController.java | 6 ++-- .../wise/portal/service/user/UserService.java | 3 +- .../service/user/impl/UserServiceImpl.java | 5 ++- .../dao/user/impl/HibernateUserDaoTest.java | 35 ++++++++++++++++--- ...StudentForgotAccountAPIControllerTest.java | 23 ++++++++++++ 7 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/wise/portal/dao/user/UserDao.java b/src/main/java/org/wise/portal/dao/user/UserDao.java index ce8f5e83b..5685e154c 100644 --- a/src/main/java/org/wise/portal/dao/user/UserDao.java +++ b/src/main/java/org/wise/portal/dao/user/UserDao.java @@ -39,8 +39,7 @@ public interface UserDao extends SimpleDao { T retrieveByMicrosoftUserId(String microsoftUserId); List retrieveAllUsernames(); T retrieveByResetPasswordKey(String resetPasswordKey); - List retrieveStudentsByNameAndBirthday(String firstName, String lastName, - Integer birthMonth, Integer birthDay); + List retrieveStudentsByName(String firstName, String lastName); List retrieveTeachersByName(String firstName, String lastName); List retrieveAllTeachers(); User retrieveTeacherById(Long id); diff --git a/src/main/java/org/wise/portal/dao/user/impl/HibernateUserDao.java b/src/main/java/org/wise/portal/dao/user/impl/HibernateUserDao.java index e33991829..ee3c799ee 100644 --- a/src/main/java/org/wise/portal/dao/user/impl/HibernateUserDao.java +++ b/src/main/java/org/wise/portal/dao/user/impl/HibernateUserDao.java @@ -298,8 +298,7 @@ public List retrieveStudentsByGender(String gender) { } @SuppressWarnings("unchecked") - public List retrieveStudentsByNameAndBirthday(String firstName, String lastName, - Integer birthMonth, Integer birthDay) { + public List retrieveStudentsByName(String firstName, String lastName) { CriteriaBuilder cb = getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(UserImpl.class); Root userRoot = cq.from(UserImpl.class); @@ -309,10 +308,6 @@ public List retrieveStudentsByNameAndBirthday(String firstName, String las .add(cb.equal(userRoot.get("userDetails").get("id"), studentUserDetailsRoot.get("id"))); predicates.add(cb.equal(studentUserDetailsRoot.get("firstname"), firstName)); predicates.add(cb.equal(studentUserDetailsRoot.get("lastname"), lastName)); - predicates.add(cb.equal( - cb.function("MONTH", Integer.class, studentUserDetailsRoot.get("birthday")), birthMonth)); - predicates.add(cb.equal( - cb.function("DAY", Integer.class, studentUserDetailsRoot.get("birthday")), birthDay)); cq.select(userRoot).where(predicates.toArray(new Predicate[predicates.size()])); TypedQuery query = entityManager.createQuery(cq); return (List) (Object) query.getResultList(); diff --git a/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIController.java b/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIController.java index e7a178533..d2e474189 100644 --- a/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIController.java +++ b/src/main/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIController.java @@ -42,10 +42,8 @@ public class StudentForgotAccountAPIController { @GetMapping("/username/search") protected String getStudentUsernames(@RequestParam String firstName, - @RequestParam String lastName, @RequestParam Integer birthMonth, - @RequestParam Integer birthDay) { - List accountsThatMatch = userService.retrieveStudentsByNameAndBirthday(firstName, - lastName, birthMonth, birthDay); + @RequestParam String lastName) { + List accountsThatMatch = userService.retrieveStudentsByName(firstName, lastName); return getUsernamesJSON(accountsThatMatch).toString(); } diff --git a/src/main/java/org/wise/portal/service/user/UserService.java b/src/main/java/org/wise/portal/service/user/UserService.java index 68f3c87fb..1b802cd41 100644 --- a/src/main/java/org/wise/portal/service/user/UserService.java +++ b/src/main/java/org/wise/portal/service/user/UserService.java @@ -149,8 +149,7 @@ User updateUserPassword(User user, String oldPassword, String newPassword) */ boolean isPasswordCorrect(User user, String password); - List retrieveStudentsByNameAndBirthday(String firstName, String lastName, - Integer birthMonth, Integer birthDay); + List retrieveStudentsByName(String firstName, String lastName); List retrieveTeachersByName(String firstName, String lastName); diff --git a/src/main/java/org/wise/portal/service/user/impl/UserServiceImpl.java b/src/main/java/org/wise/portal/service/user/impl/UserServiceImpl.java index cb2c01f8e..83558368b 100644 --- a/src/main/java/org/wise/portal/service/user/impl/UserServiceImpl.java +++ b/src/main/java/org/wise/portal/service/user/impl/UserServiceImpl.java @@ -278,9 +278,8 @@ public User retrieveByResetPasswordKey(String resetPasswordKey) { return userDao.retrieveByResetPasswordKey(resetPasswordKey); } - public List retrieveStudentsByNameAndBirthday(String firstName, String lastName, - Integer birthMonth, Integer birthDay) { - return userDao.retrieveStudentsByNameAndBirthday(firstName, lastName, birthMonth, birthDay); + public List retrieveStudentsByName(String firstName, String lastName) { + return userDao.retrieveStudentsByName(firstName, lastName); } public List retrieveTeachersByName(String firstName, String lastName) { diff --git a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java index cab6adc22..c474084a5 100644 --- a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java +++ b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java @@ -30,6 +30,7 @@ import org.springframework.security.core.userdetails.UserDetails; import org.wise.portal.domain.authentication.Gender; import org.wise.portal.domain.authentication.Schoollevel; +import org.wise.portal.domain.authentication.impl.StudentUserDetails; import org.wise.portal.domain.user.User; import org.wise.portal.junit.AbstractTransactionalDbTests; @@ -322,15 +323,41 @@ public void retrieveStudentsByGender_WithUsedGender_ShouldReturnUser() { } @Test - public void retrieveStudentsByNameAndBirthday_WithNonExistingBirthday_ShouldNotReturnAnyUser() { - List users = userDao.retrieveStudentsByNameAndBirthday("Spongebob", "Squarepants", 1, 2); + public void retrieveStudentsByName_WithNonExistingName_ShouldNotReturnAnyUser() { + List users = userDao.retrieveStudentsByName("No", "Match"); assertEquals(0, users.size()); } @Test - public void retrieveStudentsByNameAndBirthday_WithExistingBirthday_ShouldReturnUser() { - List users = userDao.retrieveStudentsByNameAndBirthday("Spongebob", "Squarepants", 1, 1); + public void retrieveStudentsByName_WithExistingName_ShouldReturnUser() { + List users = userDao.retrieveStudentsByName("Spongebob", "Squarepants"); assertEquals(1, users.size()); + assertEquals("SpongebobS", users.get(0).getUserDetails().getUsername()); + } + + @Test + public void retrieveStudentsByName_WithSeveralMatchingStudents_ShouldReturnAllUsernames() + throws Exception { + createStudentUser("Spongebob", "Squarepants", "SpongebobS2", "burger", 2, 1, Gender.MALE); + + List users = userDao.retrieveStudentsByName("Spongebob", "Squarepants"); + + assertEquals(2, users.size()); + assertTrue(users.stream().anyMatch(user -> + "SpongebobS".equals(user.getUserDetails().getUsername()))); + assertTrue(users.stream().anyMatch(user -> + "SpongebobS2".equals(user.getUserDetails().getUsername()))); + } + + @Test + public void retrieveStudentsByName_WithNoBirthday_ShouldReturnStudent() { + ((StudentUserDetails) student1.getUserDetails()).setBirthday(null); + flush(); + + List users = userDao.retrieveStudentsByName("Spongebob", "Squarepants"); + + assertEquals(1, users.size()); + assertEquals("SpongebobS", users.get(0).getUserDetails().getUsername()); } @Test diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIControllerTest.java index 57aee3622..50039ff41 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentForgotAccountAPIControllerTest.java @@ -2,7 +2,11 @@ import static org.easymock.EasyMock.*; import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import java.util.List; import java.util.Map; import org.easymock.EasyMockExtension; @@ -14,6 +18,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.wise.portal.presentation.web.controllers.APIControllerTest; import org.wise.portal.service.password.impl.PasswordServiceImpl; @@ -41,6 +47,23 @@ public void changePassword_InvalidPassword_ReturnError() throws JSONException { verify(userService); } + @Test + public void searchUsername_WithNamesOnly_ReturnsStoredUsername() throws Exception { + expect(userService.retrieveStudentsByName(STUDENT_FIRSTNAME, STUDENT_LASTNAME)) + .andReturn(List.of(student1)); + replay(userService); + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(studentForgotAccountAPIController).build(); + + mockMvc + .perform(get("/api/student/forgot/username/search") + .param("firstName", STUDENT_FIRSTNAME) + .param("lastName", STUDENT_LASTNAME)) + .andExpect(status().isOk()) + .andExpect(content().json("[\"SpongeBobS0101\"]")); + + verify(userService); + } + private void assertResponseValues(ResponseEntity> response, HttpStatus expectedStatus, String expectedMessageCode) { assertEquals(expectedStatus, response.getStatusCode()); From 36e516af459127d639c2343785d6eafe9bf8a2b1 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Thu, 29 Oct 2026 14:35:56 -0700 Subject: [PATCH 09/14] Remove birthday from student account info --- .../impl/StudentUserDetails.java | 1 - .../webapp/portal/student/account/info.jsp | 6 ---- .../admin/UserInfoControllerTest.java | 36 +++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java index 68e5a4ab7..74004cff6 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java @@ -170,7 +170,6 @@ public HashMap getInfo() { infoMap.put("Username", this.getUsername()); infoMap.put("Sign Up Date", this.getSignupdate()); infoMap.put("Gender", this.getGender().toString()); - infoMap.put("Birthday", this.getBirthday()); infoMap.put("Number of Logins", this.getNumberOfLogins().toString()); infoMap.put("Last Login", this.getLastLoginTime()); infoMap.put("Language", this.getLanguage()); diff --git a/src/main/webapp/portal/student/account/info.jsp b/src/main/webapp/portal/student/account/info.jsp index c45383db2..52e488f47 100644 --- a/src/main/webapp/portal/student/account/info.jsp +++ b/src/main/webapp/portal/student/account/info.jsp @@ -51,12 +51,6 @@ - - - () - diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java index 6b6ac5df0..e12380831 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java @@ -26,8 +26,10 @@ import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; @@ -57,6 +59,40 @@ public class UserInfoControllerTest extends APIControllerTest { private ModelMap modelMap = new ModelMap(); + @Test + public void getUserAccountInfo_StudentWithoutBirthday_ReturnsAccountInfoPageWithoutBirthday() + throws Exception { + assertStudentAccountInfoDoesNotExposeBirthday(null); + } + + @Test + public void getUserAccountInfo_StudentWithStoredBirthday_ReturnsAccountInfoPageWithoutBirthday() + throws Exception { + assertStudentAccountInfoDoesNotExposeBirthday(new Date()); + } + + @SuppressWarnings("unchecked") + private void assertStudentAccountInfoDoesNotExposeBirthday(Date birthday) throws Exception { + student1UserDetails.setBirthday(birthday); + expect(userService.retrieveUserByUsername(TEACHER_USERNAME)).andReturn(teacher1); + expect(userService.retrieveUserByUsername(STUDENT_USERNAME)).andReturn(student1); + replay(userService); + expect(studentService.isStudentAssociatedWithTeacher(student1, teacher1)).andReturn(true); + replay(studentService); + expect(runService.getRunList(student1)).andReturn(new ArrayList<>()); + replay(runService); + + String view = controller.getUserAccountInfo(teacherAuth, STUDENT_USERNAME, modelMap); + HashMap resultUserInfoMap = + (HashMap) modelMap.get("userInfoMap"); + + assertEquals("student/account/info", view); + assertFalse(resultUserInfoMap.containsKey("Birthday")); + verify(userService); + verify(studentService); + verify(runService); + } + @SuppressWarnings("unchecked") @Test public void getUserAccountInfo_TeacherOfStudent_ReturnStudentAccountInfoPage() throws Exception { From b4de1b4c97f7b4a00e20e91c2de299e7607a4e57 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Thu, 29 Oct 2026 14:50:40 -0700 Subject: [PATCH 10/14] Update migration version number --- ...rthday_nullable.sql => V4__make_student_birthday_nullable.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/resources/db/migration/{V2__make_student_birthday_nullable.sql => V4__make_student_birthday_nullable.sql} (100%) diff --git a/src/main/resources/db/migration/V2__make_student_birthday_nullable.sql b/src/main/resources/db/migration/V4__make_student_birthday_nullable.sql similarity index 100% rename from src/main/resources/db/migration/V2__make_student_birthday_nullable.sql rename to src/main/resources/db/migration/V4__make_student_birthday_nullable.sql From 94a85df47c575e5c13dbb5b1eb11e3ba07edb917 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Thu, 29 Oct 2026 17:08:46 -0700 Subject: [PATCH 11/14] Remove birthday wording from default messages Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/main/resources/i18n/i18n.properties | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/main/resources/i18n/i18n.properties b/src/main/resources/i18n/i18n.properties index f56dce2e2..e4b7ef348 100644 --- a/src/main/resources/i18n/i18n.properties +++ b/src/main/resources/i18n/i18n.properties @@ -833,8 +833,6 @@ forgotaccount.student.passwordreminder.username=Username forgotaccount.student.passwordreminder.username.description=The label for the Username field forgotaccount.student.passwordreminder.next=Next forgotaccount.student.passwordreminder.next.description=The label for the button to move to the next step -forgotaccount.student.passwordreminder.remember=REMEMBER\: your Username is your FIRST name, the first LETTER of your last name, and your BIRTHMONTH (as two digits) and BIRTHDAY (as two digits). Example\: John Doe has his birthday on March 2nd so his username would be JohnD0302. -forgotaccount.student.passwordreminder.remember.description=A reminder to help students try to remember their username by reminding them of the username convention forgotaccount.student.passwordreminder.iCantRememberUsername=I can't remember my Username forgotaccount.student.passwordreminder.iCantRememberUsername.description=The text for the link when the student can't remember their username @@ -899,8 +897,6 @@ forgotaccount.student.searchforstudentusername.firstName=First Name forgotaccount.student.searchforstudentusername.firstName.description=The label for the First Name field forgotaccount.student.searchforstudentusername.lastName=Last Name forgotaccount.student.searchforstudentusername.lastName.description=The label for the Last Name field -forgotaccount.student.searchforstudentusername.birthMonth=Birth Month -forgotaccount.student.searchforstudentusername.birthMonth.description=The label for the Birth Month field forgotaccount.student.searchforstudentusername.birthmonths.1=01 (Jan) forgotaccount.student.searchforstudentusername.birthmonths.1.description=The drop down option for January forgotaccount.student.searchforstudentusername.birthmonths.2=02 (Feb) @@ -925,8 +921,6 @@ forgotaccount.student.searchforstudentusername.birthmonths.11=11 (Nov) forgotaccount.student.searchforstudentusername.birthmonths.11.description=The drop down option for November forgotaccount.student.searchforstudentusername.birthmonths.12=12 (Dec) forgotaccount.student.searchforstudentusername.birthmonths.12.description=The drop down option for December -forgotaccount.student.searchforstudentusername.birthDay=Birth Day -forgotaccount.student.searchforstudentusername.birthDay.description=The label for the Birth Day field forgotaccount.student.searchforstudentusername.birthdates.1=01 forgotaccount.student.searchforstudentusername.birthdates.1.description=The drop down option for 01 forgotaccount.student.searchforstudentusername.birthdates.2=02 @@ -1000,10 +994,6 @@ forgotaccount.student.searchforstudentusernameresult.firstName=First Name forgotaccount.student.searchforstudentusernameresult.firstName.description=The label for the First Name field forgotaccount.student.searchforstudentusernameresult.lastName=Last Name forgotaccount.student.searchforstudentusernameresult.lastName.description=The label for the Last Name field -forgotaccount.student.searchforstudentusernameresult.birthMonth=Birth Month -forgotaccount.student.searchforstudentusernameresult.birthMonth.description=The label for the Birth Month field -forgotaccount.student.searchforstudentusernameresult.birthDay=Birth Day -forgotaccount.student.searchforstudentusernameresult.birthDay.description=The label for the Birth Day field forgotaccount.student.searchforstudentusernameresult.noMatchesFound=No matches found. You have either entered your account information differently than when you registered or have never created an account. forgotaccount.student.searchforstudentusernameresult.noMatchesFound.description=The text to tell the user there were no matches found with the given information forgotaccount.student.searchforstudentusernameresult.tryAgain=Try again @@ -1439,8 +1429,6 @@ pages.gettingstarted.student_createAccount=Click on "Create WISE Account" and ch pages.gettingstarted.student_createAccount.description=Create student account step for the student testing section of the WISE teacher getting started page pages.gettingstarted.student_fillForm=Fill in the form, entering the access code for the run you just created, and click "Submit" pages.gettingstarted.student_fillForm.description=Complete new account form step for the student testing section of the WISE teacher getting started page -pages.gettingstarted.student_username=Note that student usernames take the form of first name, followed by last initial, followed by birth month and date (JohnB0210, for example); We hope that students will find this easy to remember and will use their usernames for all the WISE projects they run in the future -pages.gettingstarted.student_username.description=Informational text about WISE student usernam format pages.gettingstarted.student_accessCodes=Note that access codes associate students with a specific classroom run (rather than a teacher, as was the case in the old version of WISE); This allows students to use a single username and password for all the WISE projects they run, no matter which teacher or class they are in pages.gettingstarted.student_accessCodes.description=Information text about student access codes pages.gettingstarted.student_signIn=After signing in as a student, you are presented with the WISE student homepage @@ -2201,12 +2189,6 @@ student.registerstudent.gender=Gender\: student.registerstudent.gender.description=Text for "Gender\:" in register student page student.registerstudent.genderSelectChoice=Select a choice. student.registerstudent.genderSelectChoice.description=Text for "Select a choice" for gender in register student page -student.registerstudent.birthMonth=Birthday (Month)\: -student.registerstudent.birthMonth.description=Text for "Birthday (Month)\:" in register student page -student.registerstudent.birthDate=Birthday (Day)\: -student.registerstudent.birthDate.description=Text for "Birthday (Day)\:" in register student page -student.registerstudent.birthDayHelp=Your birthday information will be used to create a unique (and easy to remember) Username. You'll use this Username later to sign into WISE. -student.registerstudent.birthDayHelp.description=Explanation text for how student's birthday information will be used to create a unique username in register student page. student.registerstudent.typePassword=Type a Password\: student.registerstudent.typePassword.description=The label for the password field student.registerstudent.passwordHelp=Your password can contain from 4 to 18 letters or numbers. Try to create a password that you can remember\! @@ -2357,10 +2339,6 @@ student.registerstudentsuccess.newUsername=Your new Username is\: student.registerstudentsuccess.newUsername.description=Text for "Your new Username is\:" student.registerstudentsuccess.writeDownUserInfo=WRITE DOWN your Username and Password\! student.registerstudentsuccess.writeDownUserInfo.description=Text to remind students to write down username and password after creating a new account. -student.registerstudentsuccess.rememberUsername=REMEMBER\: your Username is your FIRST name, the FIRST LETTER of your last name, and your birthday MONTH and DAY. -student.registerstudentsuccess.rememberUsername.description=Text to remind students to remember their new username. -student.registerstudentsuccess.usernameExample=Example\: "JohnD0322" is the Username for John Doe with a birthday on March 22 (3/22). -student.registerstudentsuccess.usernameExample.description=Example text for students to remember their new username. student.registerstudentsuccess.registerMoreTeammates=Click here if you have teammate(s) who also need to register. student.registerstudentsuccess.registerMoreTeammates.description=Text for "Click here if you have teammate(s) who also need to register." student.registerstudentsuccess.createNewAccount=Create Another Account @@ -2391,8 +2369,6 @@ student.studentinfo.registrationDate=WISE Registration Date\: student.studentinfo.registrationDate.description=Text for "WISE Registration Date\:" in student information page student.studentinfo.gender=Gender\: student.studentinfo.gender.description=Text for "Gender\:" in student information page -student.studentinfo.birthday=Birthday (as entered during registration)\: -student.studentinfo.birthday.description=Text for "Birthday (as entered during registration)\:" in student information page student.studentinfo.numberOfLogins=Number of Logins\: student.studentinfo.numberOfLogins.description=Text for "Number of Logins\:" in student information page student.studentinfo.runList=Run List From dbfbcea0e35bee5e46a881fe771fbbd5586a70a6 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Mon, 2 Nov 2026 11:23:40 -0800 Subject: [PATCH 12/14] Remove student birthday storage Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../impl/StudentUserDetails.java | 8 - .../migration/V4__drop_student_birthday.sql | 1 + .../V4__make_student_birthday_nullable.sql | 1 - .../wise/portal/dao/WISEHibernateTest.java | 11 +- .../HibernateAchievementDaoTest.java | 6 +- .../HibernateStudentAttendanceDaoTest.java | 6 +- .../HibernateStudentUserDetailsDaoTest.java | 6 - .../impl/HibernateUserDetailsDaoTest.java | 42 +----- .../StudentBirthdayColumnMigrationTest.java | 140 ++++++++++++++++++ .../impl/HibernateNotificationDaoTest.java | 6 +- .../dao/user/impl/HibernateUserDaoTest.java | 18 +-- .../dao/work/impl/HibernateEventDaoTest.java | 5 +- .../impl/HibernateNotebookItemDaoTest.java | 6 +- .../impl/HibernateStudentAssetDaoTest.java | 6 +- .../impl/HibernateWorkgroupDaoTest.java | 6 +- .../junit/AbstractTransactionalDbTests.java | 6 +- ...BatchCreateUserAccountsControllerTest.java | 1 - .../admin/UserInfoControllerTest.java | 15 +- .../student/StudentAPIControllerTest.java | 3 +- .../survey/SurveyAPIControllerTest.java | 1 - .../RegisterTeacherControllerTest.java | 3 +- .../service/impl/UserServiceImplTest.java | 31 ---- 22 files changed, 175 insertions(+), 153 deletions(-) create mode 100644 src/main/resources/db/migration/V4__drop_student_birthday.sql delete mode 100644 src/main/resources/db/migration/V4__make_student_birthday_nullable.sql create mode 100644 src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java diff --git a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java index 74004cff6..6f49f96e0 100644 --- a/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java +++ b/src/main/java/org/wise/portal/domain/authentication/impl/StudentUserDetails.java @@ -65,9 +65,6 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable @Transient public static final String COLUMN_NAME_GENDER = "gender"; - @Transient - public static final String COLUMN_NAME_BIRTHDAY = "birthday"; - @Transient public static final String COLUMN_NAME_NUMBEROFLOGINS = "numberoflogins"; @@ -104,11 +101,6 @@ public class StudentUserDetails extends PersistentUserDetails implements Mutable @Setter private Gender gender; - @Column(name = StudentUserDetails.COLUMN_NAME_BIRTHDAY, nullable = true) - @Getter - @Setter - private Date birthday; - @Column(name = StudentUserDetails.COLUMN_NAME_NUMBEROFLOGINS, nullable = false) @Getter @Setter diff --git a/src/main/resources/db/migration/V4__drop_student_birthday.sql b/src/main/resources/db/migration/V4__drop_student_birthday.sql new file mode 100644 index 000000000..f9b785ffa --- /dev/null +++ b/src/main/resources/db/migration/V4__drop_student_birthday.sql @@ -0,0 +1 @@ +ALTER TABLE student_user_details DROP COLUMN birthday; diff --git a/src/main/resources/db/migration/V4__make_student_birthday_nullable.sql b/src/main/resources/db/migration/V4__make_student_birthday_nullable.sql deleted file mode 100644 index 240da7e0c..000000000 --- a/src/main/resources/db/migration/V4__make_student_birthday_nullable.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE student_user_details MODIFY COLUMN birthday datetime NULL; diff --git a/src/test/java/org/wise/portal/dao/WISEHibernateTest.java b/src/test/java/org/wise/portal/dao/WISEHibernateTest.java index 4e4470761..02c1b3c97 100644 --- a/src/test/java/org/wise/portal/dao/WISEHibernateTest.java +++ b/src/test/java/org/wise/portal/dao/WISEHibernateTest.java @@ -63,12 +63,11 @@ public abstract class WISEHibernateTest extends AbstractTransactionalDbTests { @BeforeEach public void setUp() throws Exception { super.setUp(); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); - student2 = createStudentUser("Patrick", "Starr", "PatrickS", "rock", 1, 1, Gender.MALE); - student3 = createStudentUser("Sandy", "Cheeks", "SandyC", "karate", 1, 1, Gender.FEMALE); - student4 = createStudentUser("Squidward", "Tentacles", "SquidwardT", "clarinet", 1, 1, - Gender.MALE); + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); + student2 = createStudentUser("Patrick", "Starr", "PatrickS", "rock", Gender.MALE); + student3 = createStudentUser("Sandy", "Cheeks", "SandyC", "karate", Gender.FEMALE); + student4 = + createStudentUser("Squidward", "Tentacles", "SquidwardT", "clarinet", Gender.MALE); runStartTime = Calendar.getInstance().getTime(); teacher1 = createTeacherUser("Mrs", "Puff", "MrsPuff", "Mrs. Puff", "boat", "Bikini Bottom", "Water State", "Pacific Ocean", "mrspuff@bikinibottom.com", "Boating School", diff --git a/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java b/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java index 9b3391231..b71f2f79a 100644 --- a/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java +++ b/src/test/java/org/wise/portal/dao/achievement/HibernateAchievementDaoTest.java @@ -73,12 +73,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + User student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java b/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java index 76624c561..24322256a 100644 --- a/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java +++ b/src/test/java/org/wise/portal/dao/attendance/HibernateStudentAttendanceDaoTest.java @@ -77,12 +77,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + User student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateStudentUserDetailsDaoTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateStudentUserDetailsDaoTest.java index e23345b20..521d72b01 100644 --- a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateStudentUserDetailsDaoTest.java +++ b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateStudentUserDetailsDaoTest.java @@ -73,8 +73,6 @@ public class HibernateStudentUserDetailsDaoTest extends AbstractTransactionalDbT private static final Gender DEFAULT_GENDER = Gender.MALE; - private static final Date DEFAULT_BIRTHDAY = new Date(123456); - private static final String DEFAULT_ACCOUNT_QUESTION = "what is your middle name"; private static final String DEFAULT_ACCOUNT_ANSWER = "john"; @@ -159,7 +157,6 @@ protected void onSetUpBeforeTransaction() throws Exception { this.defaultUserDetails.setLastname(DEFAULT_LASTNAME); this.defaultUserDetails.setSignupdate(DEFAULT_SIGNUPDATE); this.defaultUserDetails.setGender(DEFAULT_GENDER); - this.defaultUserDetails.setBirthday(DEFAULT_BIRTHDAY); this.defaultUserDetails.setNumberOfLogins(DEFAULT_NUMBEROFLOGINS); this.defaultUserDetails.setAccountQuestion(DEFAULT_ACCOUNT_QUESTION); this.defaultUserDetails.setAccountAnswer(DEFAULT_ACCOUNT_ANSWER); @@ -228,9 +225,6 @@ public void testSave() { actualValue = String .valueOf(actualUserDetailsMap.get(StudentUserDetails.COLUMN_NAME_GENDER.toUpperCase())); assertEquals(String.valueOf(DEFAULT_GENDER.ordinal()), actualValue); - long actualTime = ((java.sql.Timestamp) actualUserDetailsMap - .get(StudentUserDetails.COLUMN_NAME_BIRTHDAY)).getTime(); - assertEquals(DEFAULT_BIRTHDAY.getTime(), actualTime); actualValue = (String) actualUserDetailsMap .get(PersistentGrantedAuthority.COLUMN_NAME_ROLE.toUpperCase()); assertTrue(defaultRolesList.contains(actualValue)); diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java index 81723ae56..6514af494 100644 --- a/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java +++ b/src/test/java/org/wise/portal/dao/authentication/impl/HibernateUserDetailsDaoTest.java @@ -19,7 +19,6 @@ import static org.junit.jupiter.api.Assertions.*; -import java.util.Date; import java.util.List; import org.junit.jupiter.api.BeforeEach; @@ -49,8 +48,8 @@ public void setUp() throws Exception { createTeacherUser("Mr", "Krabs", "MrKrabs", "Mr. Krabs", "restaurant", "Bikini Bottom", "Water State", "Pacific Ocean", "mrkrabs@bikinibottom.com", "Krusty Krab", Schoollevel.HIGH_SCHOOL, "abcdefghij"); - createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, Gender.MALE); - createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); + createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); } @Test @@ -72,7 +71,6 @@ public void retrieveByName_WithExistingStudentName_ShouldReturnUser() { assertNotNull(userDetails); assertEquals("SpongebobS", userDetails.getUsername()); assertEquals("SpongebobS", userDetails.getCoreUsername()); - assertNotNull(userDetails.getBirthday()); } @Test @@ -91,42 +89,6 @@ public void retrieveByName_WithExistingStudentUsername_ShouldNotRecomputeUsernam assertEquals("SpongebobS", reloadedStudent.getCoreUsername()); } - @Test - public void retrieveByName_WithStudentWithoutBirthday_ShouldReturnUser() { - StudentUserDetails studentUserDetails = new StudentUserDetails(); - studentUserDetails.setUsername("NoBirthdayStudent"); - studentUserDetails.setPassword("password"); - studentUserDetails.setFirstname("No"); - studentUserDetails.setLastname("Birthday"); - studentUserDetails.setGender(Gender.MALE); - studentUserDetails.setSignupdate(new Date()); - studentUserDetails.setNumberOfLogins(0); - - userDetailsDao.save(studentUserDetails); - flush(); - sessionFactory.getCurrentSession().clear(); - - StudentUserDetails reloadedStudentUserDetails = - (StudentUserDetails) userDetailsDao.retrieveByName("NoBirthdayStudent"); - - assertNotNull(reloadedStudentUserDetails); - assertNull(reloadedStudentUserDetails.getBirthday()); - } - - @Test - public void retrieveByName_WithStudentBirthday_ShouldReturnBirthdayUnchanged() { - StudentUserDetails studentUserDetails = - (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); - Date birthdayBeforeReload = studentUserDetails.getBirthday(); - flush(); - sessionFactory.getCurrentSession().clear(); - - StudentUserDetails reloadedStudentUserDetails = - (StudentUserDetails) userDetailsDao.retrieveByName("SpongebobS"); - - assertEquals(birthdayBeforeReload, reloadedStudentUserDetails.getBirthday()); - } - @Test public void retrieveAllTeacherUsernames_WhenThereAreTeachers_ShouldReturnTeacherUsernames() { List usernames = userDetailsDao.retrieveAllTeacherUsernames(); diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java new file mode 100644 index 000000000..89095bb60 --- /dev/null +++ b/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java @@ -0,0 +1,140 @@ +package org.wise.portal.dao.authentication.impl; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.util.Date; +import java.util.Properties; + +import javax.sql.DataSource; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import org.flywaydb.core.Flyway; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; +import org.springframework.test.context.TestPropertySource; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; +import org.wise.portal.domain.authentication.Gender; +import org.wise.portal.domain.authentication.impl.StudentUserDetails; +import org.wise.portal.junit.AbstractTransactionalDbTests; + +@SpringBootTest +@TestPropertySource(properties = { + "spring.datasource.url=jdbc:h2:mem:studentBirthdayColumnMigrationTest;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MySQL", + "spring.flyway.enabled=false" +}) +@Transactional(propagation = Propagation.NOT_SUPPORTED) +public class StudentBirthdayColumnMigrationTest extends AbstractTransactionalDbTests { + + @Autowired + private DataSource dataSource; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Autowired + private HibernateUserDetailsDao userDetailsDao; + + @Autowired + private PlatformTransactionManager transactionManager; + + @Test + public void migrateExistingStudentWithoutChangingUsernameAndKeepStudentRetrievable() + throws Exception { + TransactionTemplate transaction = new TransactionTemplate(transactionManager); + transaction.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); + transaction.execute(status -> { + StudentUserDetails existingStudent = new StudentUserDetails(); + existingStudent.setUsername("ExistingS0214"); + existingStudent.setPassword("password"); + existingStudent.setFirstname("Existing"); + existingStudent.setLastname("Student"); + existingStudent.setGender(Gender.FEMALE); + existingStudent.setSignupdate(new Date()); + existingStudent.setNumberOfLogins(0); + userDetailsDao.save(existingStudent); + flush(); + return null; + }); + + if (!hasBirthdayColumn()) { + jdbcTemplate.execute("ALTER TABLE student_user_details ADD birthday TIMESTAMP"); + } + jdbcTemplate.update( + "UPDATE student_user_details SET birthday = TIMESTAMP '2000-02-14' WHERE id = " + + "(SELECT id FROM user_details WHERE username = ?)", + "ExistingS0214"); + + Flyway.configure() + .dataSource(dataSource) + .locations("classpath:db/migration") + .baselineOnMigrate(true) + .baselineVersion("4") + .load() + .migrate(); + + StudentUserDetails student = retrieveStudentFromPersistenceLayerAfterMigration(); + + assertNotNull(student); + assertEquals("ExistingS0214", student.getUsername()); + assertEquals("Existing", student.getFirstname()); + assertEquals("Student", student.getLastname()); + + assertFalse(hasBirthdayColumn()); + } + + private StudentUserDetails retrieveStudentFromPersistenceLayerAfterMigration() + throws Exception { + LocalContainerEntityManagerFactoryBean migratedEntityManagerFactory = + new LocalContainerEntityManagerFactoryBean(); + migratedEntityManagerFactory.setDataSource(dataSource); + migratedEntityManagerFactory.setPackagesToScan("org.wise"); + migratedEntityManagerFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); + + Properties properties = new Properties(); + properties.setProperty("hibernate.hbm2ddl.auto", "none"); + migratedEntityManagerFactory.setJpaProperties(properties); + + try { + migratedEntityManagerFactory.afterPropertiesSet(); + EntityManagerFactory entityManagerFactory = migratedEntityManagerFactory.getObject(); + assertNotNull(entityManagerFactory); + EntityManager entityManager = entityManagerFactory.createEntityManager(); + try { + return entityManager + .createQuery( + "select student from StudentUserDetails student where student.username = :username", + StudentUserDetails.class) + .setParameter("username", "ExistingS0214") + .getSingleResult(); + } finally { + entityManager.close(); + } + } finally { + migratedEntityManagerFactory.destroy(); + } + } + + private boolean hasBirthdayColumn() throws Exception { + try (Connection connection = dataSource.getConnection()) { + DatabaseMetaData metadata = connection.getMetaData(); + try (ResultSet columns = + metadata.getColumns(null, null, "student_user_details", "birthday")) { + return columns.next(); + } + } + } +} diff --git a/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java b/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java index 4bbcd7674..c3084ab38 100644 --- a/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java +++ b/src/test/java/org/wise/portal/dao/notification/impl/HibernateNotificationDaoTest.java @@ -53,12 +53,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + User student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java index c474084a5..818f5377b 100644 --- a/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java +++ b/src/test/java/org/wise/portal/dao/user/impl/HibernateUserDaoTest.java @@ -53,9 +53,8 @@ public void setUp() throws Exception { teacher2 = createTeacherUser("Mr", "Krabs", "MrKrabs", "Mr. Krabs", "restaurant", "Bikini Bottom", "Water State", "Pacific Ocean", "mrkrabs@bikinibottom.com", "Krusty Krab", Schoollevel.HIGH_SCHOOL, "abcdefghij"); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); - student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); } @Test @@ -338,7 +337,7 @@ public void retrieveStudentsByName_WithExistingName_ShouldReturnUser() { @Test public void retrieveStudentsByName_WithSeveralMatchingStudents_ShouldReturnAllUsernames() throws Exception { - createStudentUser("Spongebob", "Squarepants", "SpongebobS2", "burger", 2, 1, Gender.MALE); + createStudentUser("Spongebob", "Squarepants", "SpongebobS2", "burger", Gender.MALE); List users = userDao.retrieveStudentsByName("Spongebob", "Squarepants"); @@ -349,17 +348,6 @@ public void retrieveStudentsByName_WithSeveralMatchingStudents_ShouldReturnAllUs "SpongebobS2".equals(user.getUserDetails().getUsername()))); } - @Test - public void retrieveStudentsByName_WithNoBirthday_ShouldReturnStudent() { - ((StudentUserDetails) student1.getUserDetails()).setBirthday(null); - flush(); - - List users = userDao.retrieveStudentsByName("Spongebob", "Squarepants"); - - assertEquals(1, users.size()); - assertEquals("SpongebobS", users.get(0).getUserDetails().getUsername()); - } - @Test public void retrieveTeachersByName_WithNonExistingName_ShouldNotReturnAnyUser() { List users = userDao.retrieveTeachersByName("Master", "Splinter"); diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java index f36722b57..0a1bb2e03 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateEventDaoTest.java @@ -66,9 +66,8 @@ public void setUp() throws Exception { teacher1 = createTeacherUser("Mrs", "Puff", "MrsPuff", "Mrs. Puff", "boat", "Bikini Bottom", "Water State", "Pacific Ocean", "mrspuff@bikinibottom.com", "Boating School", Schoollevel.COLLEGE, "1234567890"); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); - student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Long id = getNextAvailableProjectId(); String projectName = "How to be a Fry Cook"; Date startTime = Calendar.getInstance().getTime(); diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java index 0f00e39f2..67d41b99a 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateNotebookItemDaoTest.java @@ -74,12 +74,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + User student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java index 240119316..cfe0b4758 100644 --- a/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java +++ b/src/test/java/org/wise/portal/dao/work/impl/HibernateStudentAssetDaoTest.java @@ -52,12 +52,12 @@ public void setUp() throws Exception { Set periods = new TreeSet(); periods.add(period1); run.setPeriods(periods); - User student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + User student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); workgroup1 = createWorkgroup(members1, run, period1); - User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + User student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); Set members2 = new HashSet(); members2.add(student2); workgroup2 = createWorkgroup(members2, run, period1); diff --git a/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java b/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java index 0d2ebe8e0..1aff5c8a2 100644 --- a/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java +++ b/src/test/java/org/wise/portal/dao/workgroup/impl/HibernateWorkgroupDaoTest.java @@ -74,12 +74,12 @@ public void setUp() throws Exception { periods.add(period1); periods.add(period2); run.setPeriods(periods); - student1 = createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", 1, 1, - Gender.MALE); + student1 = + createStudentUser("Spongebob", "Squarepants", "SpongebobS", "burger", Gender.MALE); Set members1 = new HashSet(); members1.add(student1); createWorkgroup(members1, run, period1); - student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", 1, 1, Gender.MALE); + student2 = createStudentUser("Patrick", "Star", "PatrickS", "rock", Gender.MALE); } @Test diff --git a/src/test/java/org/wise/portal/junit/AbstractTransactionalDbTests.java b/src/test/java/org/wise/portal/junit/AbstractTransactionalDbTests.java index 6106af468..327b439c4 100644 --- a/src/test/java/org/wise/portal/junit/AbstractTransactionalDbTests.java +++ b/src/test/java/org/wise/portal/junit/AbstractTransactionalDbTests.java @@ -154,16 +154,12 @@ public User createTeacherUser(String firstName, String lastName, String username } public User createStudentUser(String firstName, String lastName, String username, String password, - int birthMonth, int birthDay, Gender gender) throws DuplicateUsernameException { + Gender gender) throws DuplicateUsernameException { StudentUserDetails userDetails = new StudentUserDetails(); userDetails.setFirstname(firstName); userDetails.setLastname(lastName); userDetails.setUsername(username); userDetails.setPassword(password); - Calendar calendar = Calendar.getInstance(); - calendar.set(Calendar.MONTH, birthMonth - 1); - calendar.set(Calendar.DAY_OF_MONTH, birthDay); - userDetails.setBirthday(new Date(calendar.getTimeInMillis())); userDetails.setGender(gender); User user = userService.createUser(userDetails); userDao.save(user); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java index 4f29e33d2..6d5d74c58 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/BatchCreateUserAccountsControllerTest.java @@ -56,7 +56,6 @@ public void onSubmit_WithUpdatedCsvLayout_CreatesNameBasedStudentAndAddsToRun() ModelAndView response = controller.onSubmit(upload, null); assertEquals("admin/account/batchcreateuseraccounts", response.getViewName()); - assertNull(studentDetails.getValue().getBirthday()); assertEquals("John", studentDetails.getValue().getFirstname()); assertEquals("Lennon", studentDetails.getValue().getLastname()); assertEquals("JohnL", studentDetails.getValue().getCoreUsername()); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java index e12380831..0d1e72972 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/admin/UserInfoControllerTest.java @@ -29,7 +29,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.List; @@ -60,20 +59,8 @@ public class UserInfoControllerTest extends APIControllerTest { private ModelMap modelMap = new ModelMap(); @Test - public void getUserAccountInfo_StudentWithoutBirthday_ReturnsAccountInfoPageWithoutBirthday() + public void getUserAccountInfo_Student_ReturnsAccountInfoPageWithoutBirthday() throws Exception { - assertStudentAccountInfoDoesNotExposeBirthday(null); - } - - @Test - public void getUserAccountInfo_StudentWithStoredBirthday_ReturnsAccountInfoPageWithoutBirthday() - throws Exception { - assertStudentAccountInfoDoesNotExposeBirthday(new Date()); - } - - @SuppressWarnings("unchecked") - private void assertStudentAccountInfoDoesNotExposeBirthday(Date birthday) throws Exception { - student1UserDetails.setBirthday(birthday); expect(userService.retrieveUserByUsername(TEACHER_USERNAME)).andReturn(teacher1); expect(userService.retrieveUserByUsername(STUDENT_USERNAME)).andReturn(student1); replay(userService); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java index b9b4ef060..03d6060c3 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/student/StudentAPIControllerTest.java @@ -253,7 +253,7 @@ public void createStudentAccount_WithMicrosoftUserId_CreateUser() } @Test - public void createStudentAccount_WithLegacyBirthdayValues_DoesNotStoreBirthday() + public void createStudentAccount_WithLegacyBirthdayValues_CreatesStudent() throws DuplicateUsernameException, InvalidNameException { HashMap studentFields = createDefaultStudentFields(); studentFields.put("birthMonth", "not-a-month"); @@ -273,7 +273,6 @@ private StudentUserDetails registerStudentAccount(Map studentFie ResponseEntity> response = studentAPIController .createStudentAccount(studentFields, request); assertEquals(STUDENT_USERNAME, response.getBody().get("username")); - assertNull(createdDetails.getValue().getBirthday()); verify(request); verify(userService); return createdDetails.getValue(); diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java index f46c065ba..705962b5e 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/survey/SurveyAPIControllerTest.java @@ -215,6 +215,5 @@ public void launchSurveyRun_NoIssues_RedirectUnit() throws Exception { replay(studentService); surveyAPIController.launchSurveyRun("dog1234-1", httpServletResponse, httpServletRequest); verify(httpServletResponse, runService, userService, workgroupService, studentService); - assertNull(createdStudentDetails.getValue().getBirthday()); } } diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/teacher/RegisterTeacherControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/teacher/RegisterTeacherControllerTest.java index b91ccf958..226f32e7e 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/teacher/RegisterTeacherControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/teacher/RegisterTeacherControllerTest.java @@ -122,8 +122,7 @@ public void testOnSubmit() throws Exception { assertEquals(SUCCESS, view); verify(mockUserService); - // test submission of form with same firstname, lastname and birthday info which - // would result in a duplicate username + // test submission of form with the same name info which would result in a duplicate username reset(mockUserService); expect(mockUserService.createUser(teacherUserDetails)).andThrow( new DuplicateUsernameException(teacherUserDetails.getUsername())); diff --git a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java index 5b5cf7fd1..52f35706f 100644 --- a/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java +++ b/src/test/java/org/wise/portal/service/impl/UserServiceImplTest.java @@ -81,20 +81,6 @@ public class UserServiceImplTest { private static final String LASTNAME = "Bob"; - private static Date BIRTHDAY; - - private static int BIRTHYEAR = 1990; - - private static int BIRTHMONTH = 12; - - private static int BIRTHDATE = 19; - - static { - Calendar cal = Calendar.getInstance(); - cal.set(BIRTHYEAR, BIRTHMONTH - 1, BIRTHDATE); - BIRTHDAY = cal.getTime(); - } - private static final Date SIGNUPDATE = Calendar.getInstance().getTime(); private static final Gender GENDER = Gender.FEMALE; @@ -125,7 +111,6 @@ public void setupCreateTest() { studentUserDetails.setLastname(LASTNAME); studentUserDetails.setSignupdate(SIGNUPDATE); studentUserDetails.setGender(GENDER); - studentUserDetails.setBirthday(BIRTHDAY); studentUserDetails.setNumberOfLogins(DEFAULT_NUMBEROFLOGINS); studentUserDetails.setAccountQuestion(DEFAULT_ACCOUNT_QUESTION); studentUserDetails.setAccountAnswer(DEFAULT_ACCOUNT_ANSWER); @@ -162,22 +147,6 @@ public void createUser_ValidStudentUser_ShouldCreateStudentUser() throws Excepti assertUserHasStudentAuthorities(); } - @Test - public void createUser_StudentWithoutBirthday_ShouldCreateNameOnlyUsername() throws Exception { - studentUserDetails.setBirthday(null); - expectStudentAuthorityLookup(); - expect(userDetailsDao.hasUsername("BillyB")).andReturn(false); - replay(userDetailsDao); - expect(passwordEncoder.encode(studentUserDetails.getPassword())).andReturn(ENCODED_PASSWORD); - replay(passwordEncoder); - - userService.createUser(studentUserDetails); - - verify(grantedAuthorityDao); - verify(userDetailsDao); - assertEquals("BillyB", studentUserDetails.getUsername()); - } - @Test public void createUser_DuplicateStudentUsername_ShouldAppendSuffixToStudentUsername() throws Exception { From ed727dc5258f4cfbac3399dc8add06fccec764a6 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Mon, 2 Nov 2026 13:04:03 -0800 Subject: [PATCH 13/14] Remove all remaining references to birthday Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com --- .../impl/PasswordReminderParameters.java | 20 ------------------- .../TeacherRegistrationAPIControllerTest.java | 2 -- 2 files changed, 22 deletions(-) diff --git a/src/main/java/org/wise/portal/domain/impl/PasswordReminderParameters.java b/src/main/java/org/wise/portal/domain/impl/PasswordReminderParameters.java index d4ed72f94..86e9dff24 100644 --- a/src/main/java/org/wise/portal/domain/impl/PasswordReminderParameters.java +++ b/src/main/java/org/wise/portal/domain/impl/PasswordReminderParameters.java @@ -52,10 +52,6 @@ public class PasswordReminderParameters extends HashMap { public static final String LAST_NAME = "lastName"; - public static final String BIRTH_MONTH = "birthMonth"; - - public static final String BIRTH_DAY = "birthDay"; - public void setUsername(String username) { this.put(USERNAME, username); } @@ -126,20 +122,4 @@ public void setLastName(String lastName) { public String getLastName() { return this.get(LAST_NAME); } - - public void setBirthMonth(String birthMonth) { - this.put(BIRTH_MONTH, birthMonth); - } - - public String getBirthMonth() { - return this.get(BIRTH_MONTH); - } - - public void setBirthDay(String birthDay) { - this.put(BIRTH_DAY, birthDay); - } - - public String getBirthDay() { - return this.get(BIRTH_DAY); - } } diff --git a/src/test/java/org/wise/portal/presentation/web/controllers/teacher/TeacherRegistrationAPIControllerTest.java b/src/test/java/org/wise/portal/presentation/web/controllers/teacher/TeacherRegistrationAPIControllerTest.java index 87bb71b75..fe32e092b 100644 --- a/src/test/java/org/wise/portal/presentation/web/controllers/teacher/TeacherRegistrationAPIControllerTest.java +++ b/src/test/java/org/wise/portal/presentation/web/controllers/teacher/TeacherRegistrationAPIControllerTest.java @@ -78,8 +78,6 @@ private HashMap createDefaultTeacherFields() { fields.put("firstName", TEACHER_FIRSTNAME); fields.put("lastName", TEACHER_LASTNAME); fields.put("schoolLevel", "COLLEGE"); - fields.put("birthMonth", "1"); - fields.put("birthDay", "1"); fields.put("gender", "MALE"); return fields; } From 5a491d4e0e23996c4b6e901a4f9d8007de343e68 Mon Sep 17 00:00:00 2001 From: Aaron Detre Date: Mon, 2 Nov 2026 13:06:30 -0800 Subject: [PATCH 14/14] Baseline migration test at V3 after renumbering drop migration to V4 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../authentication/impl/StudentBirthdayColumnMigrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java b/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java index 89095bb60..ad729521c 100644 --- a/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java +++ b/src/test/java/org/wise/portal/dao/authentication/impl/StudentBirthdayColumnMigrationTest.java @@ -82,7 +82,7 @@ public void migrateExistingStudentWithoutChangingUsernameAndKeepStudentRetrievab .dataSource(dataSource) .locations("classpath:db/migration") .baselineOnMigrate(true) - .baselineVersion("4") + .baselineVersion("3") .load() .migrate();