001package edu.pdx.cs.joy.grader.gradebook;
002
003import edu.pdx.cs.joy.ParserException;
004import org.junit.jupiter.api.Test;
005import org.w3c.dom.Document;
006
007import javax.xml.transform.TransformerException;
008import java.io.ByteArrayInputStream;
009import java.io.InputStream;
010import java.io.InputStreamReader;
011import java.io.Reader;
012import java.time.LocalDateTime;
013import java.util.List;
014
015import static org.hamcrest.MatcherAssert.assertThat;
016import static org.hamcrest.Matchers.*;
017
018public class StudentXmlTest {
019
020  @Test
021  public void letterGradeIsPersistedInXml() throws TransformerException, ParserException {
022    Student student = new Student("test");
023    LetterGrade letterGrade = LetterGrade.A;
024    student.setLetterGrade(letterGrade);
025
026    Student student2 = writeAndReadStudentAsXml(student);
027
028    assertThat(student2.getLetterGrade(), equalTo(letterGrade));
029  }
030
031  private Student writeAndReadStudentAsXml(Student student) throws TransformerException, ParserException {
032    Document doc = XmlDumper.toXml(student);
033    byte[] bytes = XmlHelper.getBytesForXmlDocument(doc);
034
035    XmlStudentParser parser = new XmlStudentParser(new InputStreamReader(new ByteArrayInputStream(bytes)));
036    return parser.parseStudent();
037  }
038
039  @Test
040  public void oneSubmissionIsPersistedInXml() throws TransformerException, ParserException {
041    Student student = new Student("test");
042    String assignmentName = "project";
043    LocalDateTime submissionTime = LocalDateTime.now().minusHours(3).withNano(0);
044    double estimatedHours = 43.5;
045    boolean isLate = true;
046
047    Grade grade = new Grade(assignmentName, Grade.NO_GRADE);
048    grade.noteSubmission(submissionTime)
049      .setEstimatedHours(estimatedHours)
050      .setIsLate(isLate);
051    student.setGrade(assignmentName, grade);
052
053    Student student2 = writeAndReadStudentAsXml(student);
054    Grade grade2 = student2.getGrade(assignmentName);
055    assertThat(grade2.getSubmissionInfos(), hasSize(1));
056
057    Grade.SubmissionInfo info = grade2.getSubmissionInfos().get(0);
058    assertThat(info.getSubmissionTime(), equalTo(submissionTime));
059    assertThat(info.getEstimatedHours(), equalTo(estimatedHours));
060    assertThat(info.isLate(), equalTo(isLate));
061  }
062
063  @Test
064  public void multipleSubmissionsArePersistedInXml() throws TransformerException, ParserException {
065    Student student = new Student("test");
066    String assignmentName = "project";
067    LocalDateTime submissionTime1 = LocalDateTime.now().minusHours(3).withNano(0);
068    double estimatedHours1 = 24.8;
069    LocalDateTime submissionTime2 = LocalDateTime.now().minusHours(4).withNano(0);
070
071    Grade grade = new Grade(assignmentName, Grade.NO_GRADE);
072    grade.noteSubmission(submissionTime1).setEstimatedHours(estimatedHours1);
073    grade.noteSubmission(submissionTime2);
074    student.setGrade(assignmentName, grade);
075
076    Student student2 = writeAndReadStudentAsXml(student);
077    Grade grade2 = student2.getGrade(assignmentName);
078    assertThat(grade2.getSubmissionInfos(), hasSize(2));
079
080    Grade.SubmissionInfo info1 = grade2.getSubmissionInfos().get(0);
081    assertThat(info1.getSubmissionTime(), equalTo(submissionTime1));
082    assertThat(info1.getEstimatedHours(), equalTo(estimatedHours1));
083
084    Grade.SubmissionInfo info2 = grade2.getSubmissionInfos().get(1);
085    assertThat(info2.getSubmissionTime(), equalTo(submissionTime2));
086    assertThat(info2.getEstimatedHours(), nullValue());
087  }
088
089  @Test
090  public void enrolledUndergraduateSectionIsPersistedInXml() throws TransformerException, ParserException {
091    Student student = new Student("test");
092    Student.Section section = Student.Section.UNDERGRADUATE;
093    student.setEnrolledSection(section);
094
095    Student student2 = writeAndReadStudentAsXml(student);
096
097    assertThat(student2.getEnrolledSection(), equalTo(section));
098  }
099
100  @Test
101  public void enrolledGraduateSectionIsPersistedInXml() throws TransformerException, ParserException {
102    Student student = new Student("test");
103    Student.Section section = Student.Section.GRADUATE;
104    student.setEnrolledSection(section);
105
106    Student student2 = writeAndReadStudentAsXml(student);
107
108    assertThat(student2.getEnrolledSection(), equalTo(section));
109  }
110
111  @Test
112  public void xmlHasNewlinesButNotIndentation() throws TransformerException {
113    Student student = new Student("test");
114    Document doc = XmlDumper.toXml(student);
115    byte[] bytes = XmlHelper.getBytesForXmlDocument(doc);
116    String string = new String(bytes);
117    assertThat(string, containsString("\n"));
118    assertThat(string.chars().filter(c -> '\n' == c).count(), greaterThan(4L));
119    assertThat(string, not(containsString(" <")));
120  }
121
122  @Test
123  public void canvasIdIsPersistedInXml() throws TransformerException, ParserException {
124    String canvasId = "canvasId";
125    Student student = new Student("studentId");
126    student.setCanvasId(canvasId);
127
128    Student student2 = writeAndReadStudentAsXml(student);
129
130    assertThat(student2.getCanvasId(), equalTo(canvasId));
131  }
132
133  @Test
134  void canParseXmlFileWithSsn() throws ParserException {
135    Reader reader = readTextResource("studentWithSsn.xml");
136    XmlStudentParser parser = new XmlStudentParser(reader);
137    Student student = parser.parseStudent();
138    assertThat(student, notNullValue());
139    assertThat(student.getId(), equalTo("studentId"));
140  }
141
142  private Reader readTextResource(String resourceName) {
143    InputStream resource = getClass().getResourceAsStream(resourceName);
144    if (resource == null) {
145      throw new IllegalArgumentException("Can't find resource " + resourceName);
146    }
147    return new InputStreamReader(resource);
148  }
149
150  @Test
151  void canParseOldXmlFileWithSubmissionTimesInsteadOfSubmissionInfo() throws ParserException {
152    XmlStudentParser parser = new XmlStudentParser(readTextResource("studentWithSubmissionDatesAndNoSubmissionInfo.xml"));
153    Student student = parser.parseStudent();
154    assertThat(student, notNullValue());
155    Grade grade = student.getGrade("Project2");
156    assertThat(grade, notNullValue());
157    List<Grade.SubmissionInfo> submissions = grade.getSubmissionInfos();
158    assertThat(submissions, hasSize(3));
159  }
160
161  @Test
162  void canParseOldXmlFileWithD2LId() throws ParserException {
163    XmlStudentParser parser = new XmlStudentParser(readTextResource("studentWithD2LId.xml"));
164    Student student = parser.parseStudent();
165    assertThat(student, notNullValue());
166    assertThat(student.getId(), equalTo("studentId"));
167    assertThat(student.getCanvasId(), nullValue());
168  }
169
170  @Test
171  void gitHubUserNameIsPersisted() throws ParserException, TransformerException {
172    String gitHubUserName = "gitHubUserName";
173    Student student = new Student("studentId");
174    student.setGitHubUserName(gitHubUserName);
175
176    Student student2 = writeAndReadStudentAsXml(student);
177
178    assertThat(student2.getGitHubUserName(), equalTo(gitHubUserName));
179  }
180
181}