001package edu.pdx.cs.joy.grader.poa;
002
003import com.google.common.eventbus.Subscribe;
004import edu.pdx.cs.joy.ParserException;
005import edu.pdx.cs.joy.grader.gradebook.Assignment;
006import edu.pdx.cs.joy.grader.gradebook.GradeBook;
007import edu.pdx.cs.joy.grader.gradebook.XmlDumper;
008import edu.pdx.cs.joy.grader.gradebook.XmlGradeBookParser;
009import org.junit.jupiter.api.BeforeEach;
010import org.junit.jupiter.api.Test;
011import org.junit.jupiter.api.io.TempDir;
012import org.mockito.ArgumentCaptor;
013
014import java.io.File;
015import java.io.IOException;
016
017import static org.hamcrest.MatcherAssert.assertThat;
018import static org.hamcrest.Matchers.any;
019import static org.hamcrest.Matchers.contains;
020import static org.hamcrest.Matchers.equalTo;
021import static org.mockito.Mockito.mock;
022import static org.mockito.Mockito.verify;
023
024public class GradeBookFileManagerTest extends EventBusTestCase {
025
026  @Override
027  @BeforeEach
028  public void setUp() {
029    super.setUp();
030    new GradeBookFileManager(this.bus);
031  }
032
033  @Test
034  public void gradeBookLoadedOnLoadGradeBookEvent(@TempDir File tempDir) throws IOException {
035    String gradeBookName = "Test Grade Book";
036    File file = writeGradeBookToFile(tempDir, gradeBookName);
037
038    GradeBookLoadedHandler handler = mock(GradeBookLoadedHandler.class);
039    this.bus.register(handler);
040
041    this.bus.post(new LoadGradeBook(file));
042
043    ArgumentCaptor<GradeBookLoaded> event = ArgumentCaptor.forClass(GradeBookLoaded.class);
044    verify(handler).handle(event.capture());
045
046    assertThat(event.getValue().getGradeBook().getClassName(), equalTo(gradeBookName));
047  }
048
049  protected File writeGradeBookToFile(File tempDir, String gradeBookName) throws IOException {
050    File file = new File(tempDir, "testGradeBook.xml");
051
052    GradeBook book = new GradeBook(gradeBookName);
053    XmlDumper dumper = new XmlDumper(file);
054    dumper.dump(book);
055
056    return file;
057  }
058
059  private interface GradeBookLoadedHandler {
060    @Subscribe
061    void handle(GradeBookLoaded event);
062  }
063
064  @Test
065  public void unhandledExceptionEventPublishedWhenLoadingBadGradeBook(@TempDir File tempDir) throws IOException {
066    File badFile = new File(tempDir, "badGradeBook.xml");
067
068    UnhandledExceptionEventHandler handler = mock(UnhandledExceptionEventHandler.class);
069    this.bus.register(handler);
070
071    this.unhandledExceptionHandler = this::doNotFailTestWhenUnhandledExceptionEncountered;
072
073    this.bus.post(new LoadGradeBook(badFile));
074
075    ArgumentCaptor<UnhandledExceptionEvent> event = ArgumentCaptor.forClass(UnhandledExceptionEvent.class);
076    verify(handler).handle(event.capture());
077
078    assertThat(event.getValue().getUnhandledException(), any(Throwable.class));
079  }
080
081  private interface UnhandledExceptionEventHandler {
082    @Subscribe
083    void handle(UnhandledExceptionEvent event);
084  }
085
086  @Test
087  public void gradeBookSavedToFileOnSaveGradeBookEvent(@TempDir File tempDir) throws IOException, ParserException {
088    String gradeBookName = "Test Grade Book";
089    File file = writeGradeBookToFile(tempDir, gradeBookName);
090
091    GradeBookLoadedHandler handler = mock(GradeBookLoadedHandler.class);
092    this.bus.register(handler);
093
094    this.bus.post(new LoadGradeBook(file));
095
096    ArgumentCaptor<GradeBookLoaded> event = ArgumentCaptor.forClass(GradeBookLoaded.class);
097    verify(handler).handle(event.capture());
098
099    GradeBook book = event.getValue().getGradeBook();
100    Assignment poa = new Assignment("poa", 1.0);
101    book.addAssignment(poa);
102
103    this.bus.post(new SaveGradeBook(book));
104
105    book = readGradeBookFromFile(file);
106    assertThat(book.getAssignmentNames(), contains(poa.getName()));
107  }
108
109  private GradeBook readGradeBookFromFile(File file) throws IOException, ParserException {
110    XmlGradeBookParser parser = new XmlGradeBookParser(file);
111    return parser.parse();
112  }
113
114}