package com.mattrixwv.cipherstream.monosubstitution; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import org.slf4j.Logger; import com.mattrixwv.cipherstream.exceptions.InvalidInputException; import com.mattrixwv.cipherstream.exceptions.InvalidKeywordException; @ExtendWith(MockitoExtension.class) public class VigenereTest{ @InjectMocks private Vigenere cipher; @Mock private Logger logger; //Variables private static final String INPUT_STRING = "MeSsage to^encode"; private static final String INPUT_STRING_CLEAN = "MESSAGETOENCODE"; private static final String OUTPUT_STRING = "WiQooxh ds^cjqfgo"; private static final String OUTPUT_STRING_CLEAN = "WIQOOXHDSCJQFGO"; private static final String KEYWORD = "ke yw*ord"; private static final String KEYWORD_CLEAN = "KEYWORD"; private ArrayList offset; @BeforeEach public void setup(){ offset = new ArrayList<>(List.of(10, 4, 24, 22, 14, 17, 3)); } @Test public void testConstructor_default(){ cipher = new Vigenere(); assertFalse(cipher.preserveCapitals); assertFalse(cipher.preserveWhitespace); assertFalse(cipher.preserveSymbols); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); } @Test public void testConstructor_preservesCapitals(){ cipher = new Vigenere(true, false, false); assertTrue(cipher.preserveCapitals); assertFalse(cipher.preserveWhitespace); assertFalse(cipher.preserveSymbols); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); } @Test public void testConstructor_preservesWhitespace(){ cipher = new Vigenere(false, true, false); assertFalse(cipher.preserveCapitals); assertTrue(cipher.preserveWhitespace); assertFalse(cipher.preserveSymbols); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); } @Test public void testConstructor_preservesSymbols(){ cipher = new Vigenere(false, false, true); assertFalse(cipher.preserveCapitals); assertFalse(cipher.preserveWhitespace); assertTrue(cipher.preserveSymbols); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); } @Test public void testSetOffset(){ cipher.keyword = KEYWORD_CLEAN; cipher.setOffset(); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); verify(logger, times(1)).debug("Setting offset array from keyword"); verify(logger, times(1)).debug("Offset {}", offset); } @Test public void testSetInputString(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.setInputString(INPUT_STRING); assertEquals(INPUT_STRING, cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", INPUT_STRING); verify(logger, never()).debug("Removing case"); verify(logger, never()).debug("Removing whitespace"); verify(logger, never()).debug("Removing symbols"); verify(logger, times(1)).debug("Cleaned input string '{}'", INPUT_STRING); } @Test public void testSetInputString_noCapitals(){ cipher.preserveCapitals = false; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.setInputString(INPUT_STRING); assertEquals(INPUT_STRING.toUpperCase(), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", INPUT_STRING); verify(logger, times(1)).debug("Removing case"); verify(logger, never()).debug("Removing whitespace"); verify(logger, never()).debug("Removing symbols"); verify(logger, times(1)).debug("Cleaned input string '{}'", INPUT_STRING.toUpperCase()); } @Test public void testSetInputString_noWhitespace(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = false; cipher.preserveSymbols = true; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.setInputString(INPUT_STRING); assertEquals(INPUT_STRING.replaceAll("\\s", ""), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", INPUT_STRING); verify(logger, never()).debug("Removing case"); verify(logger, times(1)).debug("Removing whitespace"); verify(logger, never()).debug("Removing symbols"); verify(logger, times(1)).debug("Cleaned input string '{}'", INPUT_STRING.replaceAll("\\s", "")); } @Test public void testSetInputString_noSymbols(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = false; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.setInputString(INPUT_STRING); assertEquals(INPUT_STRING.replaceAll("[^a-zA-Z\\s]", ""), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", INPUT_STRING); verify(logger, never()).debug("Removing case"); verify(logger, never()).debug("Removing whitespace"); verify(logger, times(1)).debug("Removing symbols"); verify(logger, times(1)).debug("Cleaned input string '{}'", INPUT_STRING.replaceAll("[^a-zA-Z\\s]", "")); } @Test public void testSetInputString_blank(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; assertThrows(InvalidInputException.class, () -> { cipher.setInputString(""); }); assertEquals("", cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", ""); verify(logger, never()).debug("Removing case"); verify(logger, never()).debug("Removing whitespace"); verify(logger, never()).debug("Removing symbols"); verify(logger, times(1)).debug("Cleaned input string '{}'", ""); } @Test public void testSetInputString_null(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; assertThrows(InvalidInputException.class, () -> { cipher.setInputString(null); }); assertEquals("", cipher.inputString); verify(logger, never()).debug(eq("Original input string '{}'"), anyString()); verify(logger, never()).debug("Removing case"); verify(logger, never()).debug("Removing whitespace"); verify(logger, never()).debug("Removing symbols"); verify(logger, never()).debug(eq("Cleaned input string '{}'"), anyString()); } @Test public void testSetKeyword(){ cipher.setKeyword(KEYWORD); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); verify(logger, times(1)).debug("Original keyword '{}'", KEYWORD); verify(logger, times(1)).debug("Removing case"); verify(logger, times(1)).debug("Removing all non-letter characters"); verify(logger, times(1)).debug("Clean keyword '{}'", KEYWORD_CLEAN); } @Test public void testSetKeyword_blank(){ assertThrows(InvalidKeywordException.class, () -> { cipher.setKeyword(""); }); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); verify(logger, times(1)).debug("Original keyword '{}'", ""); verify(logger, times(1)).debug("Removing case"); verify(logger, times(1)).debug("Removing all non-letter characters"); verify(logger, times(1)).debug("Clean keyword '{}'", ""); } @Test public void testSetKeyword_null(){ assertThrows(InvalidKeywordException.class, () -> { cipher.setKeyword(null); }); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); verify(logger, never()).debug(eq("Original keyword '{}'"), anyString()); verify(logger, never()).debug("Removing case"); verify(logger, never()).debug("Removing all non-letter characters"); verify(logger, never()).debug(eq("Clean keyword '{}'"), anyString()); } @Test public void testEncode(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.inputString = INPUT_STRING; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.encode(); assertEquals(OUTPUT_STRING, cipher.outputString); verify(logger, times(1)).debug("Encoding"); verify(logger, times(17)).debug(eq("Working character {}"), anyChar()); verify(logger, times(2)).debug("Encoding uppercase"); verify(logger, times(1)).debug("Wrapping around to A"); verify(logger, times(13)).debug("Encoding lowercase"); verify(logger, times(5)).debug("Wrapping around to a"); verify(logger, times(17)).debug(eq("Encoded character {}"), anyChar()); verify(logger, times(1)).debug("Encoded message '{}'", OUTPUT_STRING); } @Test public void testDecode(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.inputString = OUTPUT_STRING; cipher.keyword = KEYWORD_CLEAN; cipher.offset = offset; cipher.decode(); assertEquals(INPUT_STRING, cipher.outputString); verify(logger, times(1)).debug("Decoding"); verify(logger, times(17)).debug(eq("Working character {}"), anyChar()); verify(logger, times(2)).debug("Decoding uppercase"); verify(logger, times(1)).debug("Wrapping around to Z"); verify(logger, times(13)).debug("Decoding lowercase"); verify(logger, times(5)).debug("Wrapping around to z"); verify(logger, times(17)).debug(eq("Decoded character {}"), anyChar()); verify(logger, times(1)).debug("Decoded message '{}'", INPUT_STRING); } @Test public void testGetters(){ cipher.inputString = INPUT_STRING; cipher.outputString = OUTPUT_STRING; cipher.keyword = KEYWORD; cipher.offset = offset; assertEquals(INPUT_STRING, cipher.getInputString()); assertEquals(OUTPUT_STRING, cipher.getOutputString()); assertEquals(KEYWORD, cipher.getKeyword()); assertEquals(offset, cipher.getOffsets()); } @Test public void testReset(){ cipher.inputString = INPUT_STRING; cipher.outputString = OUTPUT_STRING; cipher.keyword = KEYWORD; cipher.offset = offset; cipher.reset(); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals("", cipher.keyword); assertEquals(new ArrayList<>(), cipher.offset); verify(logger, times(1)).debug("Resetting fields"); } @Test public void testPracticalEncoding(){ cipher = new Vigenere(true, true, true); String output = cipher.encode(KEYWORD, INPUT_STRING); assertEquals(INPUT_STRING, cipher.inputString); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); assertEquals(OUTPUT_STRING, cipher.outputString); assertEquals(OUTPUT_STRING, output); } @Test public void testPracticalEncoding_clean(){ cipher = new Vigenere(false, false, false); String output = cipher.encode(KEYWORD, INPUT_STRING); assertEquals(INPUT_STRING_CLEAN, cipher.inputString); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); assertEquals(OUTPUT_STRING_CLEAN, cipher.outputString); assertEquals(OUTPUT_STRING_CLEAN, output); } @Test public void testPracticalDecoding(){ cipher = new Vigenere(true, true, true); String output = cipher.decode(KEYWORD, OUTPUT_STRING); assertEquals(OUTPUT_STRING, cipher.inputString); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); assertEquals(INPUT_STRING, cipher.outputString); assertEquals(INPUT_STRING, output); } @Test public void testPracticalDecoding_clean(){ cipher = new Vigenere(false, false, false); String output = cipher.decode(KEYWORD, OUTPUT_STRING); assertEquals(OUTPUT_STRING_CLEAN, cipher.inputString); assertEquals(KEYWORD_CLEAN, cipher.keyword); assertEquals(offset, cipher.offset); assertEquals(INPUT_STRING_CLEAN, cipher.outputString); assertEquals(INPUT_STRING_CLEAN, output); } }