diff --git a/.gitignore b/.gitignore index 288a569..5b48466 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ local.properties .settings/ .loadpath .recommenders +JavaDoc/ # External tool builders .externalToolBuilders/ @@ -60,3 +61,5 @@ local.properties #.project /target/ api-key.txt + + diff --git a/pom.xml b/pom.xml index 6e457ab..a5ee55a 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,12 @@ guava-annotations r03 + + org.junit.jupiter + junit-jupiter-engine + 5.4.0 + test + diff --git a/src/main/java/edu/mills/cs180a/wordui/FXMLController.java b/src/main/java/edu/mills/cs180a/wordui/FXMLController.java index 8439ec7..09a81a2 100644 --- a/src/main/java/edu/mills/cs180a/wordui/FXMLController.java +++ b/src/main/java/edu/mills/cs180a/wordui/FXMLController.java @@ -132,9 +132,13 @@ private void configureButtons() { .or(freqValidProperty.not()) .or(wordTextField.textProperty().isEmpty()) .or(definitionTextArea.textProperty().isEmpty())); - - // TODO: Disable the Create button if an existing entry is selected or any + // Disable the Create button if an existing entry is selected or any // field is empty or invalid. + createButton.disableProperty() + .bind(listView.getSelectionModel().selectedItemProperty().isNotNull() + .or(wordTextField.textProperty().isEmpty()) + .or(freqValidProperty.not()) + .or(definitionTextArea.textProperty().isEmpty())); } // A frequency is valid if it is an integer and is at least 0. diff --git a/src/main/java/edu/mills/cs180a/wordui/model/SampleData.java b/src/main/java/edu/mills/cs180a/wordui/model/SampleData.java index f9d8846..9262d32 100644 --- a/src/main/java/edu/mills/cs180a/wordui/model/SampleData.java +++ b/src/main/java/edu/mills/cs180a/wordui/model/SampleData.java @@ -42,37 +42,54 @@ private static int getFrequencyFromSummary(FrequencySummary fs, int year) { return 0; } - // TODO: Move to spring-swagger-wordnik-client @VisibleForTesting protected static int getFrequencyByYear(WordApi wordApi, String word, int year) { FrequencySummary fs = wordApi.getWordFrequency(word, "false", year, year); return getFrequencyFromSummary(fs, year); } - private static WordRecord buildWordRecord(String word, Map definition) { - WordApi wordApi = client.buildClient(WordApi.class); - return new WordRecord( - word, + @VisibleForTesting + protected static WordOfTheDay getWordOfTheDay(WordsApi wordsApi) { + return wordsApi.getWordOfTheDay(); + } + + /** + * Downloads the Wordnik Word of the Day and adds it to a list. + * + * @param the list to add the word to + */ + public static void addWordOfTheDay(ObservableList backingList, WordsApi wordsApi, WordApi wordApi) { + WordOfTheDay word = getWordOfTheDay(wordsApi); + List definitions = word.getDefinitions(); + if (definitions != null && !definitions.isEmpty()) { + Object definition = definitions.get(0); + if (definition instanceof Map) { + @SuppressWarnings("unchecked") + Map definitionAsMap = (Map) definition; + backingList.add(buildWordRecord(word.getWord(), definitionAsMap, wordApi)); // pass in API + } + } + } + + private static WordRecord buildWordRecord(String word, Map definition, WordApi wordApi) { + return new WordRecord(word, getFrequencyByYear(wordApi, word, FREQ_YEAR), definition.get("text").toString()); } + /** + * Populates the passed list with sample words and Wordnik's Word of the Day. + * + * @param the list to be populated + */ public static void fillSampleData(ObservableList backingList) { try { client = ApiClientHelper.getApiClient(); WordsApi wordsApi = client.buildClient(WordsApi.class); - WordOfTheDay word = wordsApi.getWordOfTheDay(); - List definitions = word.getDefinitions(); - if (definitions != null && !definitions.isEmpty()) { - Object definition = definitions.get(0); - if (definition instanceof Map) { - @SuppressWarnings("unchecked") - Map definitionAsMap = (Map) definition; - backingList.add(buildWordRecord(word.getWord(), definitionAsMap)); - } - } - } catch (IOException e) { - System.err.println("Unable to get API key."); + WordApi wordApi = client.buildClient(WordApi.class); + addWordOfTheDay(backingList, wordsApi, wordApi); + } catch (IOException ex) { + System.out.println("Probably couldn't access the API client: " + ex); } backingList.add(new WordRecord("buffalo", 5153, "The North American bison.")); diff --git a/src/test/java/edu/mills/cs180a/wordui/model/SampleDataTest.java b/src/test/java/edu/mills/cs180a/wordui/model/SampleDataTest.java index a7808ec..00bf564 100644 --- a/src/test/java/edu/mills/cs180a/wordui/model/SampleDataTest.java +++ b/src/test/java/edu/mills/cs180a/wordui/model/SampleDataTest.java @@ -5,24 +5,44 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.util.ArrayList; import java.util.List; import java.util.Map; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; import edu.mills.cs180a.wordnik.client.api.WordApi; +import edu.mills.cs180a.wordnik.client.api.WordsApi; import edu.mills.cs180a.wordnik.client.model.FrequencySummary; +import edu.mills.cs180a.wordnik.client.model.WordOfTheDay; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; class SampleDataTest { private final WordApi mockWordApi = mock(WordApi.class); + private final WordsApi mockWordsApi = mock(WordsApi.class); + private static final String WORD_OF_THE_DAY = "yucca"; private static final Map FREQS_MAP = Map.of( "apple", makeFrequencySummary(List.of(makeMap(2000, 339), makeMap(2001, 464))), - "orange", makeFrequencySummary(List.of(makeMap(2000, 774), makeMap(2001, 941)))); + "orange", makeFrequencySummary(List.of(makeMap(2000, 774), makeMap(2001, 941))), + WORD_OF_THE_DAY, makeFrequencySummary(List.of(makeMap(2020, 37), makeMap(2012, 57)))); + private static final String DEFINITION1 = "Definition #1"; + private static final String DEFINITION2 = "Definition #2"; + private static final String DEFINITION3 = "Definition #3"; + private static final String[] DEFINITION_ARRAY = new String[] {DEFINITION1, DEFINITION2, DEFINITION3}; + private static final List DEFINITIONS = makeDefinitions(DEFINITION_ARRAY); + @BeforeEach void setup() { when(mockWordApi.getWordFrequency(anyString(), anyString(), anyInt(), anyInt())) .thenAnswer(invocation -> FREQS_MAP.get(invocation.getArgument(0))); + + WordOfTheDay mockWordOfTheDay = mock(WordOfTheDay.class); + when(mockWordsApi.getWordOfTheDay()).thenReturn(mockWordOfTheDay); + when(mockWordOfTheDay.getWord()).thenReturn(WORD_OF_THE_DAY); + when(mockWordOfTheDay.getDefinitions()).thenReturn(DEFINITIONS); } private static Map makeMap(int year, int count) { @@ -30,6 +50,18 @@ private static Map makeMap(int year, int count) { SampleData.FREQ_COUNT_KEY, count); } + private static Map makeDefinition(String definition) { + return Map.of("text", definition); + } + + private static List makeDefinitions(String[] definitions) { + List definitionList = new ArrayList(); + for (int i = 0; i < definitions.length; i++) { + definitionList.add(makeDefinition(definitions[i])); + } + return definitionList; + } + private static FrequencySummary makeFrequencySummary(List freqs) { FrequencySummary fs = mock(FrequencySummary.class); when(fs.getFrequency()).thenReturn(freqs); @@ -38,8 +70,37 @@ private static FrequencySummary makeFrequencySummary(List freqs) { @ParameterizedTest @CsvSource({"apple,2000,339", "apple,2001,464", "apple,2020,0", "orange,2000,774", - "orange,2001,941", "orange,2050,0"}) + "orange,2001,941", "orange,2050,0", "yucca,2020,37", "yucca,2012,57"}) void testGetFrequencyFromSummary(String word, int year, int count) { assertEquals(count, SampleData.getFrequencyByYear(mockWordApi, word, year)); } + + @SuppressWarnings("unchecked") + @Test + void testGetWordOfTheDay() { + WordOfTheDay wordOfTheDay = SampleData.getWordOfTheDay(mockWordsApi); + + Map definition1 = (Map) wordOfTheDay.getDefinitions().get(0); + Map definition2 = (Map) wordOfTheDay.getDefinitions().get(1); + Map definition3 = (Map) wordOfTheDay.getDefinitions().get(2); + + assertEquals(WORD_OF_THE_DAY, wordOfTheDay.getWord()); + assertEquals(DEFINITIONS, wordOfTheDay.getDefinitions()); + assertEquals(DEFINITION1, definition1.get("text").toString()); + assertEquals(DEFINITION2, definition2.get("text").toString()); + assertEquals(DEFINITION3, definition3.get("text").toString()); + } + + @Test + void testAddWordOfTheDay() { + ObservableList wordRecordList = FXCollections.observableArrayList(); + assertEquals(0, wordRecordList.size()); + SampleData.addWordOfTheDay(wordRecordList, mockWordsApi, mockWordApi); + assertEquals(1, wordRecordList.size()); + + WordRecord wordRecord = wordRecordList.get(0); + assertEquals(WORD_OF_THE_DAY, wordRecord.getWord()); + assertEquals(DEFINITION1, wordRecord.getDefinition()); + assertEquals(57, wordRecord.getFrequency()); + } }