package com.mattrixwv.cipherstream.monosubstitution; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; 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 AffineTest{ @InjectMocks private Affine cipher; @Mock private Logger logger; //Variables private static final String DECODED_STRING = "MEssage to^encode"; private static final String DECODED_STRING_CLEAN = "messagetoencode"; private static final String ENCODED_STRING = "PBtthlb yz^burzwb"; private static final String ENCODED_STRING_CLEAN = "pbtthlbyzburzwb"; private static final int KEY_1 = 5; private static final int KEY_2 = 7; @Test public void testConstructor_default(){ cipher = new Affine(); assertFalse(cipher.preserveCapitals); assertFalse(cipher.preserveSymbols); assertFalse(cipher.preserveWhitespace); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals(0, cipher.key1); assertEquals(0, cipher.key2); } @Test public void testConstructor_preservesCapitals(){ cipher = new Affine(true, false, false); assertTrue(cipher.preserveCapitals); assertFalse(cipher.preserveSymbols); assertFalse(cipher.preserveWhitespace); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals(0, cipher.key1); assertEquals(0, cipher.key2); } @Test public void testConstructor_preservesWhitespace(){ cipher = new Affine(false, true, false); assertFalse(cipher.preserveCapitals); assertFalse(cipher.preserveSymbols); assertTrue(cipher.preserveWhitespace); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals(0, cipher.key1); assertEquals(0, cipher.key2); } @Test public void testConstructor_preservesSymbols(){ cipher = new Affine(false, false, true); assertFalse(cipher.preserveCapitals); assertTrue(cipher.preserveSymbols); assertFalse(cipher.preserveWhitespace); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals(0, cipher.key1); assertEquals(0, cipher.key2); } @Test public void testKey1(){ cipher.setKey1(KEY_1); assertEquals(KEY_1, cipher.key1); verify(logger, times(1)).debug("Setting key1 {}", KEY_1); verify(logger, times(1)).debug("Cleaned key1 {}", KEY_1); } @Test public void testSetKey1_notPrime(){ assertThrows(InvalidKeywordException.class, () -> { cipher.setKey1(2); }); verify(logger, times(1)).debug("Setting key1 {}", 2); verify(logger, never()).debug("Cleaned key1 {}", 2); } @Test public void testSetKey1_negative(){ cipher.setKey1(-27); assertEquals(25, cipher.key1); verify(logger, times(1)).debug("Setting key1 {}", -27); verify(logger, times(1)).debug("Cleaned key1 {}", 25); } @Test public void testSetKey1_large(){ cipher.setKey1(KEY_1 + 26); assertEquals(KEY_1, cipher.key1); verify(logger, times(1)).debug("Setting key1 {}", KEY_1 + 26); verify(logger, times(1)).debug("Cleaned key1 {}", KEY_1); } @Test public void testSetKey2(){ cipher.setKey2(KEY_2); assertEquals(KEY_2, cipher.key2); verify(logger, times(1)).debug("Setting key2 {}", KEY_2); verify(logger, times(1)).debug("Cleaned key2 {}", KEY_2); } @Test public void testSetKey2_negative(){ cipher.setKey2(-27); assertEquals(25, cipher.key2); verify(logger, times(1)).debug("Setting key2 {}", -27); verify(logger, times(1)).debug("Cleaned key2 {}", cipher.key2); } @Test public void testSetKey2_large(){ cipher.setKey2(KEY_2 + 26); assertEquals(KEY_2, cipher.key2); verify(logger, times(1)).debug("Setting key2 {}", KEY_2 + 26); verify(logger, times(1)).debug("Cleaned key2 {}", KEY_2); } @Test public void testSetInputString(){ cipher.preserveCapitals = true; cipher.preserveSymbols = true; cipher.preserveWhitespace = true; cipher.setInputString(DECODED_STRING); assertEquals(DECODED_STRING, cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", DECODED_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 '{}'", DECODED_STRING); } @Test public void testSetInputString_noCapitals(){ cipher.preserveCapitals = false; cipher.preserveSymbols = true; cipher.preserveWhitespace = true; cipher.setInputString(DECODED_STRING); assertEquals(DECODED_STRING.toLowerCase(), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", DECODED_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 '{}'", DECODED_STRING.toLowerCase()); } @Test public void testSetInputString_noWhitespace(){ cipher.preserveCapitals = true; cipher.preserveSymbols = true; cipher.preserveWhitespace = false; cipher.setInputString(DECODED_STRING); assertEquals(DECODED_STRING.replaceAll("\\s", ""), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", DECODED_STRING); verify(logger, never()).debug("Removing case"); verify(logger, times(1)).debug("Removing whitespace"); verify(logger, never()).debug("Removing sybols"); verify(logger, times(1)).debug("Cleaned input string '{}'", DECODED_STRING.replaceAll("\\s", "")); } @Test public void testSetInputString_noSymbols(){ cipher.preserveCapitals = true; cipher.preserveSymbols = false; cipher.preserveWhitespace = true; cipher.setInputString(DECODED_STRING); assertEquals(DECODED_STRING.replaceAll("[^a-zA-Z\\s]", ""), cipher.inputString); verify(logger, times(1)).debug("Original input string '{}'", DECODED_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 '{}'", DECODED_STRING.replaceAll("[^a-zA-Z\\s]", "")); } @Test public void testSetInputString_null(){ cipher.preserveCapitals = true; cipher.preserveSymbols = true; cipher.preserveWhitespace = true; 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 testSetInputString_blank(){ cipher.preserveCapitals = true; cipher.preserveSymbols = true; cipher.preserveWhitespace = true; 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 testEncode(){ cipher.preserveCapitals = true; cipher.preserveWhitespace = true; cipher.preserveSymbols = true; cipher.inputString = DECODED_STRING; cipher.key1 = KEY_1; cipher.key2 = KEY_2; cipher.encode(); assertEquals(ENCODED_STRING, cipher.outputString); verify(logger, times(1)).debug("Encoding"); verify(logger, times(17)).debug(eq("Current char {}"), anyChar()); verify(logger, times(15)).debug(eq("Encoded char {}"), anyChar()); verify(logger, times(1)).debug("Saving output string '{}'", ENCODED_STRING); } @Test public void testDecode(){ cipher.preserveCapitals = true; cipher.preserveSymbols = true; cipher.preserveWhitespace = true; cipher.inputString = ENCODED_STRING; cipher.key1 = KEY_1; cipher.key2 = KEY_2; cipher.decode(); assertEquals(DECODED_STRING, cipher.outputString); verify(logger, times(1)).debug("Decoding"); verify(logger, times(1)).debug("Key1 inverse {}", 21); verify(logger, times(17)).debug(eq("Current char {}"), anyChar()); verify(logger, times(15)).debug(eq("Decoded char {}"), anyChar()); verify(logger, times(1)).debug("Saving output string '{}'", DECODED_STRING); } @Test public void testGetters(){ cipher.inputString = DECODED_STRING; cipher.outputString = ENCODED_STRING; cipher.key1 = KEY_1; cipher.key2 = KEY_2; assertEquals(DECODED_STRING, cipher.getInputString()); assertEquals(ENCODED_STRING, cipher.getOutputString()); assertEquals(KEY_1, cipher.getKey1()); assertEquals(KEY_2, cipher.getKey2()); } @Test public void testReset(){ cipher.inputString = DECODED_STRING; cipher.outputString = ENCODED_STRING; cipher.key1 = KEY_1; cipher.key2 = KEY_2; cipher.reset(); assertEquals("", cipher.inputString); assertEquals("", cipher.outputString); assertEquals(0, cipher.key1); assertEquals(0, cipher.key2); verify(logger, times(1)).debug("Resetting fields"); } @Test public void testPracticalEncoding(){ cipher = new Affine(true, true, true); String output = cipher.encode(KEY_1, KEY_2, DECODED_STRING); assertEquals(DECODED_STRING, cipher.inputString); assertEquals(KEY_1, cipher.key1); assertEquals(KEY_2, cipher.key2); assertEquals(ENCODED_STRING, cipher.outputString); assertEquals(ENCODED_STRING, output); } @Test public void testPracticalEncoding_clean(){ cipher = new Affine(false, false, false); String output = cipher.encode(KEY_1, KEY_2, DECODED_STRING); assertEquals(DECODED_STRING_CLEAN, cipher.inputString); assertEquals(KEY_1, cipher.key1); assertEquals(KEY_2, cipher.key2); assertEquals(ENCODED_STRING_CLEAN, cipher.outputString); assertEquals(ENCODED_STRING_CLEAN, output); } @Test public void testPracticalDecoding(){ cipher = new Affine(true, true, true); String output = cipher.decode(KEY_1, KEY_2, ENCODED_STRING); assertEquals(ENCODED_STRING, cipher.inputString); assertEquals(KEY_1, cipher.key1); assertEquals(KEY_2, cipher.key2); assertEquals(DECODED_STRING, cipher.outputString); assertEquals(DECODED_STRING, output); } @Test public void testpracticalDecoding_clean(){ cipher = new Affine(false, false, false); String output = cipher.decode(KEY_1, KEY_2, ENCODED_STRING); assertEquals(ENCODED_STRING_CLEAN, cipher.inputString); assertEquals(KEY_1, cipher.key1); assertEquals(KEY_2, cipher.key2); assertEquals(DECODED_STRING_CLEAN, cipher.outputString); assertEquals(DECODED_STRING_CLEAN, output); } }