From 1189102c07439703dfd3734d5bee4bf2b8b5caea Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 20:07:22 +0100 Subject: [PATCH 1/6] control menu with custom InputStream --- src/main/java/PasswordManager.java | 11 +++++++++-- src/main/java/PasswordManagerInterface.java | 4 +++- src/test/java/PasswordManagerTest.java | 6 +++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index 97c4711..0a16d66 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -1,7 +1,14 @@ +import java.io.BufferedInputStream; +import java.io.InputStream; + public class PasswordManager implements PasswordManagerInterface { public static void main(String[] args) { PasswordManager pm = new PasswordManager(); - pm.showMenu(); + + while (true) { + InputStream inputStream = System.in; + pm.showMenu(inputStream); + } } public PasswordManager() { @@ -19,7 +26,7 @@ public class PasswordManager implements PasswordManagerInterface { } @Override - public void showMenu() { + public void showMenu(InputStream inputStream) { } } diff --git a/src/main/java/PasswordManagerInterface.java b/src/main/java/PasswordManagerInterface.java index 385532f..bd8421a 100644 --- a/src/main/java/PasswordManagerInterface.java +++ b/src/main/java/PasswordManagerInterface.java @@ -1,7 +1,9 @@ +import java.io.InputStream; + public interface PasswordManagerInterface { public static void main(String[] args) { }; public void listVaults(); public void openVault(); - public void showMenu(); + public void showMenu(InputStream inputStream); } diff --git a/src/test/java/PasswordManagerTest.java b/src/test/java/PasswordManagerTest.java index b18cf0d..7f3bc47 100644 --- a/src/test/java/PasswordManagerTest.java +++ b/src/test/java/PasswordManagerTest.java @@ -1,6 +1,10 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; + import static org.junit.jupiter.api.Assertions.*; @@ -30,6 +34,6 @@ class PasswordManagerTest { @Test void showMenu() { - pm.showMenu(); + pm.showMenu(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); } } From d3edeba81b300a5a9b27ba086e03c281157de382 Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 20:14:36 +0100 Subject: [PATCH 2/6] implement exiting menu --- src/main/java/PasswordManager.java | 22 ++++++++++++++++++++-- src/test/java/PasswordManagerTest.java | 10 +++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index 0a16d66..ddc68c9 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -1,14 +1,18 @@ -import java.io.BufferedInputStream; import java.io.InputStream; +import java.util.Scanner; public class PasswordManager implements PasswordManagerInterface { + + boolean running = true; + public static void main(String[] args) { PasswordManager pm = new PasswordManager(); - while (true) { + while (pm.running) { InputStream inputStream = System.in; pm.showMenu(inputStream); } + System.exit(0); } public PasswordManager() { @@ -27,6 +31,20 @@ public class PasswordManager implements PasswordManagerInterface { @Override public void showMenu(InputStream inputStream) { + StringBuilder sb = new StringBuilder(); + Scanner scan = new Scanner(inputStream); + + sb.append("ciip Gruppe 8 - Password Manager\n\n"); + + sb.append("Menu:\n"); + sb.append("- exit: e\n"); + System.out.println(sb + "\n"); + + String input = scan.nextLine(); + + if (input.equals("e")) { + running = false; + } } } diff --git a/src/test/java/PasswordManagerTest.java b/src/test/java/PasswordManagerTest.java index 7f3bc47..81e4427 100644 --- a/src/test/java/PasswordManagerTest.java +++ b/src/test/java/PasswordManagerTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.nio.charset.StandardCharsets; +import java.util.NoSuchElementException; import static org.junit.jupiter.api.Assertions.*; @@ -34,6 +35,13 @@ class PasswordManagerTest { @Test void showMenu() { - pm.showMenu(new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8))); + ByteArrayInputStream virtualConsoleInput = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(virtualConsoleInput)); + } + + @Test + void exitMenu() { + pm.showMenu(new ByteArrayInputStream("e\n".getBytes(StandardCharsets.UTF_8))); + assertFalse(pm.running); } } From fcccecae9eed30c4980beaa77081611e47b96fb7 Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 20:24:10 +0100 Subject: [PATCH 3/6] do not exit menu after wrong input --- src/main/java/PasswordManager.java | 18 +++++++++++----- src/main/java/PasswordManagerInterface.java | 3 ++- src/test/java/PasswordManagerTest.java | 24 ++++++++++++++++----- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index ddc68c9..a8cec33 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -1,4 +1,7 @@ +import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; import java.util.Scanner; public class PasswordManager implements PasswordManagerInterface { @@ -7,10 +10,11 @@ public class PasswordManager implements PasswordManagerInterface { public static void main(String[] args) { PasswordManager pm = new PasswordManager(); + InputStream inputStream = System.in; + OutputStream outputStream = System.out; while (pm.running) { - InputStream inputStream = System.in; - pm.showMenu(inputStream); + pm.showMenu(inputStream, outputStream); } System.exit(0); } @@ -21,7 +25,6 @@ public class PasswordManager implements PasswordManagerInterface { @Override public void listVaults() { - } @Override @@ -30,16 +33,21 @@ public class PasswordManager implements PasswordManagerInterface { } @Override - public void showMenu(InputStream inputStream) { + public void showMenu(InputStream inputStream, OutputStream outputStream) { StringBuilder sb = new StringBuilder(); Scanner scan = new Scanner(inputStream); + running = true; sb.append("ciip Gruppe 8 - Password Manager\n\n"); sb.append("Menu:\n"); sb.append("- exit: e\n"); - System.out.println(sb + "\n"); + try { + outputStream.write((sb + "\n").getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } String input = scan.nextLine(); diff --git a/src/main/java/PasswordManagerInterface.java b/src/main/java/PasswordManagerInterface.java index bd8421a..da179e3 100644 --- a/src/main/java/PasswordManagerInterface.java +++ b/src/main/java/PasswordManagerInterface.java @@ -1,9 +1,10 @@ import java.io.InputStream; +import java.io.OutputStream; public interface PasswordManagerInterface { public static void main(String[] args) { }; public void listVaults(); public void openVault(); - public void showMenu(InputStream inputStream); + public void showMenu(InputStream inputStream, OutputStream outputStream); } diff --git a/src/test/java/PasswordManagerTest.java b/src/test/java/PasswordManagerTest.java index 81e4427..8125195 100644 --- a/src/test/java/PasswordManagerTest.java +++ b/src/test/java/PasswordManagerTest.java @@ -1,8 +1,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; +import java.io.*; import java.nio.charset.StandardCharsets; import java.util.NoSuchElementException; @@ -35,13 +34,28 @@ class PasswordManagerTest { @Test void showMenu() { - ByteArrayInputStream virtualConsoleInput = new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); - assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(virtualConsoleInput)); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(getEmptyStringInputStream(), outputStream)); + assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); } @Test void exitMenu() { - pm.showMenu(new ByteArrayInputStream("e\n".getBytes(StandardCharsets.UTF_8))); + pm.showMenu(new ByteArrayInputStream("e\n".getBytes(StandardCharsets.UTF_8)), System.out); assertFalse(pm.running); } + + @Test + void doNotExitMenuAfterWrongInput() { + pm.showMenu(new ByteArrayInputStream("__\n".getBytes(StandardCharsets.UTF_8)), System.out); + assertTrue(pm.running); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(getEmptyStringInputStream(), outputStream)); + assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); + } + + private ByteArrayInputStream getEmptyStringInputStream() { + return new ByteArrayInputStream("".getBytes(StandardCharsets.UTF_8)); + } } From 138b9a02bf045cf6aa6f6f99b8204fa9f41de82f Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 20:44:57 +0100 Subject: [PATCH 4/6] refactor input output stream handling --- src/main/java/PasswordManager.java | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index a8cec33..8c8b7dd 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -7,24 +7,29 @@ import java.util.Scanner; public class PasswordManager implements PasswordManagerInterface { boolean running = true; + InputStream inputStream = System.in; + OutputStream outputStream = System.out; public static void main(String[] args) { PasswordManager pm = new PasswordManager(); - InputStream inputStream = System.in; - OutputStream outputStream = System.out; while (pm.running) { - pm.showMenu(inputStream, outputStream); + pm.showMenu(null, null); } System.exit(0); } public PasswordManager() { - System.out.println("Hello World"); + try { + outputStream.write("Hello World\n".getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } } @Override public void listVaults() { + } @Override @@ -34,6 +39,13 @@ public class PasswordManager implements PasswordManagerInterface { @Override public void showMenu(InputStream inputStream, OutputStream outputStream) { + if (inputStream == null) { + inputStream = this.inputStream; + } + if (outputStream == null) { + outputStream = this.outputStream; + } + StringBuilder sb = new StringBuilder(); Scanner scan = new Scanner(inputStream); running = true; From 97e48e530f007735ccc3b666ed9f4b4954b41660 Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 21:00:06 +0100 Subject: [PATCH 5/6] navigate to list vaults in menu --- src/main/java/PasswordManager.java | 20 ++++++------ src/main/java/PasswordManagerInterface.java | 2 +- src/test/java/PasswordManagerTest.java | 34 ++++++++++++++++++--- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index 8c8b7dd..4db3fd7 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -14,7 +14,7 @@ public class PasswordManager implements PasswordManagerInterface { PasswordManager pm = new PasswordManager(); while (pm.running) { - pm.showMenu(null, null); + pm.showMenu(); } System.exit(0); } @@ -29,7 +29,11 @@ public class PasswordManager implements PasswordManagerInterface { @Override public void listVaults() { - + try { + outputStream.write("Vaults:\n".getBytes(StandardCharsets.UTF_8)); + } catch (IOException e) { + e.printStackTrace(); + } } @Override @@ -38,14 +42,7 @@ public class PasswordManager implements PasswordManagerInterface { } @Override - public void showMenu(InputStream inputStream, OutputStream outputStream) { - if (inputStream == null) { - inputStream = this.inputStream; - } - if (outputStream == null) { - outputStream = this.outputStream; - } - + public void showMenu() { StringBuilder sb = new StringBuilder(); Scanner scan = new Scanner(inputStream); running = true; @@ -53,6 +50,7 @@ public class PasswordManager implements PasswordManagerInterface { sb.append("ciip Gruppe 8 - Password Manager\n\n"); sb.append("Menu:\n"); + sb.append("- list vaults: l:\n"); sb.append("- exit: e\n"); try { @@ -65,6 +63,8 @@ public class PasswordManager implements PasswordManagerInterface { if (input.equals("e")) { running = false; + } else if (input.equals("l")) { + listVaults(); } } } diff --git a/src/main/java/PasswordManagerInterface.java b/src/main/java/PasswordManagerInterface.java index da179e3..b7a7616 100644 --- a/src/main/java/PasswordManagerInterface.java +++ b/src/main/java/PasswordManagerInterface.java @@ -6,5 +6,5 @@ public interface PasswordManagerInterface { }; public void listVaults(); public void openVault(); - public void showMenu(InputStream inputStream, OutputStream outputStream); + public void showMenu(); } diff --git a/src/test/java/PasswordManagerTest.java b/src/test/java/PasswordManagerTest.java index 8125195..d811272 100644 --- a/src/test/java/PasswordManagerTest.java +++ b/src/test/java/PasswordManagerTest.java @@ -1,7 +1,9 @@ import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.NoSuchElementException; @@ -17,6 +19,12 @@ class PasswordManagerTest { pm = new PasswordManager(); } + @BeforeEach + void reset() { + pm.outputStream = System.out; + pm.inputStream = System.in; + } + @Test void constructor() { assertInstanceOf(PasswordManager.class, pm); @@ -32,26 +40,42 @@ class PasswordManagerTest { pm.openVault(); } + @Test + void menuNavigationListVaults() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + pm.inputStream = new ByteArrayInputStream("l\n".getBytes(StandardCharsets.UTF_8)); + pm.outputStream = outputStream; + pm.showMenu(); + assertTrue(outputStream.toString().endsWith("Vaults:\n")); + } + @Test void showMenu() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(getEmptyStringInputStream(), outputStream)); + pm.inputStream = getEmptyStringInputStream(); + pm.outputStream = outputStream; + assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu()); assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); } @Test void exitMenu() { - pm.showMenu(new ByteArrayInputStream("e\n".getBytes(StandardCharsets.UTF_8)), System.out); + pm.inputStream = new ByteArrayInputStream("e\n".getBytes(StandardCharsets.UTF_8)); + pm.showMenu(); assertFalse(pm.running); } @Test void doNotExitMenuAfterWrongInput() { - pm.showMenu(new ByteArrayInputStream("__\n".getBytes(StandardCharsets.UTF_8)), System.out); + pm.inputStream = new ByteArrayInputStream("__\n".getBytes(StandardCharsets.UTF_8)); + pm.showMenu(); assertTrue(pm.running); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu(getEmptyStringInputStream(), outputStream)); + pm.inputStream = getEmptyStringInputStream(); + pm.outputStream = outputStream; + + assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu()); assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); } From 143653c2bc39157a8b0a5f7f58c8cd364a56e3e7 Mon Sep 17 00:00:00 2001 From: binsky Date: Mon, 24 Jan 2022 21:09:14 +0100 Subject: [PATCH 6/6] select vault in menu --- src/main/java/PasswordManager.java | 54 ++++++++++++++++++++------ src/test/java/PasswordManagerTest.java | 13 ++++++- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/src/main/java/PasswordManager.java b/src/main/java/PasswordManager.java index 4db3fd7..29960fd 100644 --- a/src/main/java/PasswordManager.java +++ b/src/main/java/PasswordManager.java @@ -1,7 +1,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.Scanner; public class PasswordManager implements PasswordManagerInterface { @@ -20,17 +23,17 @@ public class PasswordManager implements PasswordManagerInterface { } public PasswordManager() { - try { - outputStream.write("Hello World\n".getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - e.printStackTrace(); - } + println("Hello World"); } @Override public void listVaults() { + println("Vaults:"); + } + + private void println(String output) { try { - outputStream.write("Vaults:\n".getBytes(StandardCharsets.UTF_8)); + outputStream.write((output + "\n").getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } @@ -47,17 +50,14 @@ public class PasswordManager implements PasswordManagerInterface { Scanner scan = new Scanner(inputStream); running = true; - sb.append("ciip Gruppe 8 - Password Manager\n\n"); + sb.append("\nciip Gruppe 8 - Password Manager\n\n"); sb.append("Menu:\n"); sb.append("- list vaults: l:\n"); + sb.append("- select vault: v x (replace x with vault id)\n"); sb.append("- exit: e\n"); - try { - outputStream.write((sb + "\n").getBytes(StandardCharsets.UTF_8)); - } catch (IOException e) { - e.printStackTrace(); - } + println(sb.toString()); String input = scan.nextLine(); @@ -65,6 +65,36 @@ public class PasswordManager implements PasswordManagerInterface { running = false; } else if (input.equals("l")) { listVaults(); + } else if (input.startsWith("v")) { + String vaultAction = (input.replace('v', ' ')).trim(); + int vaultId = -1; + + try { + vaultId = Integer.parseInt(vaultAction); + } catch (NumberFormatException e) { + println("-- please enter a correct vault id"); + } + + if (vaultId >= 0) { + try { + int internalOptionCounter = 0; + ArrayList options = new ArrayList<>(); + + for (Method m : Class.forName("Vault").getDeclaredMethods()) { // returns all declared methods including private or protected + try { + if (Modifier.isPublic(this.getClass().getDeclaredMethod(m.getName()).getModifiers())) { // filter out methods that are not public (using Modifier) or have arguments (using getDeclaredMethod) + options.add(m.getName()); + println(internalOptionCounter + " - " + m.getName()); + internalOptionCounter++; + } + } catch (NoSuchMethodException ignore) { + // println("No method with name " + m.getName() + " found"); + } + } + } catch (ClassNotFoundException e) { + println("-- vaults not implemented yet"); + } + } } } } diff --git a/src/test/java/PasswordManagerTest.java b/src/test/java/PasswordManagerTest.java index d811272..149e12f 100644 --- a/src/test/java/PasswordManagerTest.java +++ b/src/test/java/PasswordManagerTest.java @@ -49,13 +49,22 @@ class PasswordManagerTest { assertTrue(outputStream.toString().endsWith("Vaults:\n")); } + @Test + void menuNavigationOpenVault() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + pm.inputStream = new ByteArrayInputStream("v 0\n".getBytes(StandardCharsets.UTF_8)); + pm.outputStream = outputStream; + pm.showMenu(); + assertTrue(outputStream.toString().endsWith("-- vaults not implemented yet\n")); + } + @Test void showMenu() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); pm.inputStream = getEmptyStringInputStream(); pm.outputStream = outputStream; assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu()); - assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); + assertTrue(outputStream.toString().startsWith("\nciip Gruppe 8")); } @Test @@ -76,7 +85,7 @@ class PasswordManagerTest { pm.outputStream = outputStream; assertThrowsExactly(NoSuchElementException.class, () -> pm.showMenu()); - assertTrue(outputStream.toString().startsWith("ciip Gruppe 8")); + assertTrue(outputStream.toString().startsWith("\nciip Gruppe 8")); } private ByteArrayInputStream getEmptyStringInputStream() {