001package edu.pdx.cs.joy.grader; 002 003import com.google.common.io.ByteStreams; 004import edu.pdx.cs.joy.grader.gradebook.Assignment; 005import edu.pdx.cs.joy.grader.gradebook.Grade; 006import edu.pdx.cs.joy.grader.gradebook.GradeBook; 007import edu.pdx.cs.joy.grader.gradebook.Student; 008import org.hamcrest.MatcherAssert; 009import org.junit.jupiter.api.Test; 010 011import java.io.ByteArrayInputStream; 012import java.io.ByteArrayOutputStream; 013import java.io.IOException; 014import java.time.LocalDateTime; 015import java.util.HashMap; 016import java.util.zip.ZipEntry; 017import java.util.zip.ZipInputStream; 018import java.util.zip.ZipOutputStream; 019 020import static org.hamcrest.MatcherAssert.assertThat; 021import static org.hamcrest.core.IsEqual.equalTo; 022import static org.hamcrest.core.IsNull.notNullValue; 023import static org.hamcrest.core.IsNull.nullValue; 024 025public class AndroidZipFixerTest { 026 027 @Test 028 public void unitTestEntriesAreIgnored() { 029 assertThat(AndroidZipFixer.getFixedEntryName("src/test/java"), equalTo(null)); 030 } 031 032 @Test 033 public void androidTestEntriesAreIgnored() { 034 assertThat(AndroidZipFixer.getFixedEntryName("src/androidTest/java"), equalTo(null)); 035 } 036 037 @Test 038 public void androidTestInDirectoryIsIgnored() { 039 String entry = "student/app/src/androidTest/java/edu/pdx/cs/joy/"; 040 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 041 } 042 043 @Test 044 public void buildDirectoriesAreIgnored() { 045 assertThat(AndroidZipFixer.getFixedEntryName("build"), equalTo(null)); 046 } 047 048 @Test 049 public void buildGradleRemainsAtTopLevel() { 050 assertThat(AndroidZipFixer.getFixedEntryName("build.gradle"), equalTo("build.gradle")); 051 } 052 053 @Test 054 public void buildGradleInAppDirectoryRemainsInItsDirectory() { 055 assertThat(AndroidZipFixer.getFixedEntryName("app/build.gradle"), equalTo("app/build.gradle")); 056 } 057 058 @Test 059 public void buildGradleInNonAppDirectoryIsMoveToTop() { 060 assertThat(AndroidZipFixer.getFixedEntryName("fred/build.gradle"), equalTo("build.gradle")); 061 } 062 063 @Test 064 public void buildGradleInAppDirectoryInOtherDirectoryIsMovedToTopAppDirectory() { 065 assertThat(AndroidZipFixer.getFixedEntryName("fred/app/build.gradle"), equalTo("app/build.gradle")); 066 } 067 068 @Test 069 public void gradlePropertiesRemainsAtTopLevel() { 070 assertThat(AndroidZipFixer.getFixedEntryName("gradle.properties"), equalTo("gradle.properties")); 071 } 072 073 @Test 074 public void gradlePropertiesMovedToTopLevel() { 075 assertThat(AndroidZipFixer.getFixedEntryName("fred/gradle.properties"), equalTo("gradle.properties")); 076 } 077 078 @Test 079 public void gradleDirectoryMovedToTopLevel() { 080 assertThat(AndroidZipFixer.getFixedEntryName("fred/gradle"), equalTo("gradle")); 081 } 082 083 @Test 084 public void gradlewScriptMovedToTopLevel() { 085 assertThat(AndroidZipFixer.getFixedEntryName("fred/gradlew"), equalTo("gradlew")); 086 } 087 088 @Test 089 public void settingsDotGradleScriptMovedToTopLevel() { 090 assertThat(AndroidZipFixer.getFixedEntryName("fred/settings.gradle"), equalTo("settings.gradle")); 091 } 092 093 @Test 094 public void localDotPropertiesIsIgnored() { 095 assertThat(AndroidZipFixer.getFixedEntryName("fred/local.properties"), equalTo(null)); 096 } 097 098 @Test 099 public void gradleWrapperJarFileMovedToTopLevel() { 100 String entry = "gradle/wrapper/gradle-wrapper.jar"; 101 assertThat(AndroidZipFixer.getFixedEntryName("student/" + entry), equalTo(entry)); 102 } 103 104 @Test 105 public void gradlewDotBatIsIgnored() { 106 assertThat(AndroidZipFixer.getFixedEntryName("student/gradlew.bat"), equalTo(null)); 107 } 108 109 @Test 110 public void javaSourceRemainsAtTopLevel() { 111 String entry = "app/src/main/java/edu/pdx/cs/joy/student/client/MainActivity.java"; 112 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(entry)); 113 } 114 115 @Test 116 public void javaSourceIsMovedToTopLevel() { 117 String entry = "app/src/main/java/edu/pdx/cs/joy/student/client/MainActivity.java"; 118 assertThat(AndroidZipFixer.getFixedEntryName("directory/" + entry), equalTo(entry)); 119 } 120 121 @Test 122 public void ideaDirectoryIsIgnored() { 123 String entry = "5Proj/apptbook-gwt/.idea/artifacts/"; 124 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 125 } 126 127 @Test 128 public void imlFilesAreIgnored() { 129 assertThat(AndroidZipFixer.getFixedEntryName("project.iml"), equalTo(null)); 130 } 131 132 @Test 133 public void resourcesDirectoryIsMovedToTopLevel() { 134 String resource = "app/src/main/res/mipmap-mdpi/ic_launcher.png"; 135 String entry = "5Proj/apptbook-gwt" + resource; 136 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(resource)); 137 } 138 139 @Test 140 public void srcIsAddedToMainDirectory() { 141 String entry = "main/java/edu/pdx/cs/joy/student/client/PrettyPrinter.java"; 142 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo("app/src/" + entry)); 143 } 144 145 @Test 146 public void macosDirectoryIsIgnored() { 147 String entry = "__MACOSX/apptbook-gwt/._pom.xml"; 148 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 149 } 150 @Test 151 public void mainThatIsNotSourceMainIsIgnored() { 152 String entry = "apptbook-gwt/out/production/main/"; 153 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 154 } 155 156 @Test 157 public void directoryWithJavaIsMovedToSrcMain() { 158 String entry = "student/java/edu/pdx/cs/joy/student/client/Appointment.java"; 159 String fixed = "app/src/main/java/edu/pdx/cs/joy/student/client/Appointment.java"; 160 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(fixed)); 161 } 162 163 @Test 164 public void srcTestIsIgnored() { 165 String entry = "apptbook-gwt-submission/src/test/java/edu/"; 166 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 167 } 168 169 @Test 170 public void srcAndroidTestIsIgnored() { 171 String entry = "apptbook-gwt-submission/src/androidTest/java/edu/"; 172 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(null)); 173 } 174 175 @Test 176 public void directoryWithJavaSubPackageNamedDomainIsMovedToSrcMain() { 177 String entry = "student/java/edu/pdx/cs/joy/student/client/domain/Appointment.java"; 178 String fixed = "app/src/main/java/edu/pdx/cs/joy/student/client/domain/Appointment.java"; 179 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(fixed)); 180 } 181 182 @Test 183 public void directoryWithJavaSubPackageNamedDomainRemainsInSrcMain() { 184 String entry = "app/src/main/java/edu/pdx/cs/joy/student/client/domain/Appointment.java"; 185 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(entry)); 186 } 187 188 @Test 189 public void fileSubmittedWithSubmitProgramIsMovedToSrcMainJava() { 190 String entry = "edu/pdx/cs/joy/student/client/domain/Appointment.java"; 191 String fixed = "app/src/main/java/edu/pdx/cs/joy/student/client/domain/Appointment.java"; 192 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(fixed)); 193 } 194 195 @Test 196 public void packageWithMainIsMovedToAppropriateLocation() { 197 String entry = "AndroidAppointmentBook/app/src/main/java/edu/pdx/cs/joy/student/androidappointmentbook/ui/main/SectionsPagerAdapter.java"; 198 String fixed = "app/src/main/java/edu/pdx/cs/joy/student/androidappointmentbook/ui/main/SectionsPagerAdapter.java"; 199 assertThat(AndroidZipFixer.getFixedEntryName(entry), equalTo(fixed)); 200 } 201 202 @Test 203 public void pomFileInTargetIsIgnored() { 204 String entry = "airline-gwt/target/airline/META-INF/maven/edu.pdx.cs.joy.student/airline-gwt/pom.xml"; 205 assertThat(AndroidZipFixer.getFixedEntryName(entry), nullValue()); 206 } 207 208 @Test 209 public void dsStoreIsIgnored() { 210 String entry = "student/airline/src/main/.DS_Store"; 211 assertThat(AndroidZipFixer.getFixedEntryName(entry), nullValue()); 212 } 213 214 @Test 215 public void manifestContainsStudentId() { 216 String studentId = "studentId"; 217 218 GradeBook book = new GradeBook("test"); 219 book.addStudent(new Student(studentId)); 220 221 AndroidZipFixer fixer = new AndroidZipFixer(book); 222 assertThat(fixer.getManifestEntriesForStudent(studentId).get(Submit.ManifestAttributes.USER_ID), equalTo(studentId)); 223 } 224 225 @Test 226 public void manifestContainsStudentName() { 227 228 GradeBook book = new GradeBook("test"); 229 Student student = new Student("studentId"); 230 student.setFirstName("First"); 231 student.setLastName("Last"); 232 book.addStudent(student); 233 234 AndroidZipFixer fixer = new AndroidZipFixer(book); 235 assertThat(fixer.getManifestEntriesForStudent("studentId").get(Submit.ManifestAttributes.USER_NAME), equalTo(student.getFullName())); 236 237 } 238 239 @Test 240 public void manifestContainsSubmissionTime() { 241 GradeBook book = new GradeBook("test"); 242 String studentId = "studentId"; 243 Student student = new Student(studentId); 244 book.addStudent(student); 245 246 Assignment gwtProject = new Assignment("Project5", 12.0); 247 book.addAssignment(gwtProject); 248 249 Grade grade = new Grade(gwtProject, Grade.NO_GRADE); 250 LocalDateTime submissionTime = LocalDateTime.now(); 251 grade.noteSubmission(submissionTime); 252 253 student.setGrade(gwtProject, grade); 254 255 AndroidZipFixer fixer = new AndroidZipFixer(book); 256 MatcherAssert.assertThat(fixer.getManifestEntriesForStudent(studentId).get(Submit.ManifestAttributes.SUBMISSION_TIME), equalTo(Submit.ManifestAttributes.formatSubmissionTime(submissionTime))); 257 } 258 259 @Test 260 public void manifestContainsLatestSubmissionTime() { 261 GradeBook book = new GradeBook("test"); 262 String studentId = "studentId"; 263 Student student = new Student(studentId); 264 book.addStudent(student); 265 266 Assignment gwtProject = new Assignment("Project5", 12.0); 267 book.addAssignment(gwtProject); 268 269 Grade grade = new Grade(gwtProject, Grade.NO_GRADE); 270 LocalDateTime now = LocalDateTime.now(); 271 LocalDateTime firstSubmissionTime = now.minusDays(1); 272 grade.noteSubmission(firstSubmissionTime); 273 LocalDateTime secondSubmissionTime = now.minusHours(6); 274 grade.noteSubmission(secondSubmissionTime); 275 276 student.setGrade(gwtProject, grade); 277 278 AndroidZipFixer fixer = new AndroidZipFixer(book); 279 MatcherAssert.assertThat(fixer.getManifestEntriesForStudent(studentId).get(Submit.ManifestAttributes.SUBMISSION_TIME), equalTo(Submit.ManifestAttributes.formatSubmissionTime(secondSubmissionTime))); 280 } 281 282 @Test 283 public void missingSubmissionDateResultsInNullManifestEntry() { 284 GradeBook book = new GradeBook("test"); 285 String studentId = "studentId"; 286 Student student = new Student(studentId); 287 book.addStudent(student); 288 289 Assignment gwtProject = new Assignment("Project5", 12.0); 290 book.addAssignment(gwtProject); 291 292 Grade grade = new Grade(gwtProject, Grade.NO_GRADE); 293 294 student.setGrade(gwtProject, grade); 295 296 AndroidZipFixer fixer = new AndroidZipFixer(book); 297 assertThat(fixer.getManifestEntriesForStudent(studentId).get(Submit.ManifestAttributes.SUBMISSION_TIME), equalTo(null)); 298 } 299 300 @Test 301 public void contentsOfZipEntriesAreNotModified() throws IOException { 302 String entryName = "build.gradle"; 303 String entryContent = "This is a test entry"; 304 305 ByteArrayOutputStream zippedBytes = new ByteArrayOutputStream(); 306 ZipOutputStream zos = new ZipOutputStream(zippedBytes); 307 zos.setMethod(ZipOutputStream.DEFLATED); 308 309 ZipEntry entry = new ZipEntry(entryName); 310 zos.putNextEntry(entry); 311 zos.write(entryContent.getBytes()); 312 zos.closeEntry(); 313 zos.close(); 314 315 AndroidZipFixer fixer = new AndroidZipFixer(new GradeBook("test")); 316 ByteArrayOutputStream fixedBytes = new ByteArrayOutputStream(); 317 fixer.fixZipFile(new ByteArrayInputStream(zippedBytes.toByteArray()), fixedBytes, new HashMap<>()); 318 319 ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(fixedBytes.toByteArray())); 320 321 ZipEntry fixedEntry = zis.getNextEntry(); 322 while (fixedEntry != null) { 323 if (fixedEntry.getName().equals(entryName)) { 324 break; 325 } 326 fixedEntry = zis.getNextEntry(); 327 } 328 329 assertThat(fixedEntry, notNullValue()); 330 331 ByteArrayOutputStream fixedEntryBytes = new ByteArrayOutputStream(); 332 ByteStreams.copy(zis, fixedEntryBytes); 333 String fixedEntryContent = new String(fixedEntryBytes.toByteArray()); 334 335 assertThat(fixedEntryContent, equalTo(entryContent)); 336 337 338 } 339 340}