Commit ea70ec84 authored by Jostein Hjortland Tysse's avatar Jostein Hjortland Tysse
Browse files
parents 3ba29da5 f91133b7
......@@ -17,7 +17,10 @@ Oppgavene skal lagres i `ovinger/src/main/java/oving7`.
I begge delene er antageligvis vanskelighetsgraden stigende. Alle er høyst eksamensrelevante og det anbefales følgelig å ta en titt på samtlige.
For å få 1 poeng på øvingen så må du gjennomføre kravene som står nedenfor under hver enkelt del, altså minimum én oppgave per del.
For å få 2 poeng på øvingen må det gjennomføres til sammen *4* valgfrie oppgaver fra del 1 og 2.
### Del 1: Arv
Velg og gjennomfør *minst én* av oppgavene om arv:
......
......@@ -10,7 +10,7 @@ public class HomeFolderReceiptHandler implements IReceiptHandler {
@Override
public SelfCheckout readReceipt(String filename, SelfCheckout selfCheckout) throws IOException {
try (Scanner scanner = new Scanner(getReceiptFolderPath())) {
try (Scanner scanner = new Scanner(getReceiptPath(filename).toFile())) {
String phoneNumber = scanner.nextLine();
if (!phoneNumber.equals("null")) {
selfCheckout.registerPhoneNumber(phoneNumber);
......@@ -26,7 +26,7 @@ public class HomeFolderReceiptHandler implements IReceiptHandler {
@Override
public void writeReceipt(String filename, SelfCheckout selfCheckout) throws IOException {
Files.createDirectories(getReceiptFolderPath());
try (PrintWriter writer = new PrintWriter(getReceiptFolderPath().resolve(filename + ".txt").toFile())) {
try (PrintWriter writer = new PrintWriter(getReceiptPath(filename).toFile())) {
writer.println(selfCheckout.getPhoneNumber());
for (Item item : selfCheckout.getShoppingCartItems()) {
writer.println(String.format("%s;%s;%s", item.getName(), item.getPrice(), item.getCategory()));
......@@ -35,6 +35,11 @@ public class HomeFolderReceiptHandler implements IReceiptHandler {
}
@Override
public Path getReceiptPath(String filename) {
return getReceiptFolderPath().resolve(filename + ".txt");
}
private static Path getReceiptFolderPath() {
return Path.of(System.getProperty("user.home"), "tdt4100files", "receipts");
}
......
package selfcheckout;
import java.io.IOException;
import java.nio.file.Path;
public interface IReceiptHandler {
......@@ -8,4 +9,6 @@ public interface IReceiptHandler {
void writeReceipt(String filename, SelfCheckout selfCheckout) throws IOException;
Path getReceiptPath(String filename);
}
......@@ -41,7 +41,7 @@ public class Item {
public boolean equals(Object other) {
if (other instanceof Item) {
Item otherItem = (Item) other;
return this.name.equals(getName()) && this.price == otherItem.getPrice()
return this.name.equals(otherItem.getName()) && this.price == otherItem.getPrice()
&& this.category.equals(otherItem.getCategory());
}
return false;
......
......@@ -28,19 +28,27 @@ public class SelfCheckout {
this.campaigns = new ArrayList<>(campaigns);
}
public SelfCheckout(String day, String password) {
validateDay(day);
validatePassword(password);
this.day = day;
this.password = password;
this.adminMode = false;
this.shoppingCart = new ArrayList<>();
this.campaigns = new ArrayList<>();
}
public List<Item> getShoppingCartItems() {
return new ArrayList<>(this.shoppingCart);
}
// Del 4 a)
public void removeFromCart(int index) {
if (!this.adminMode) {
if (!this.adminMode || this.shoppingCart.size() < 1) {
throw new IllegalStateException("Illegal operation");
}
this.shoppingCart.remove(index);
}
// Del 2 a)
public void activateAdminMode(String password) {
if (this.adminMode) {
throw new IllegalStateException("Admin mode is already active!");
......
package selfcheckout;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
......@@ -27,22 +26,22 @@ public class SelfCheckoutController {
private List<Item> selectableItemsList;
@FXML
public Button login, adminMode, deleteItem, backButton, checkout, scanReceipt;
private Button login, adminMode, deleteItem, backButton, checkout, scanReceipt;
@FXML
public TextArea checkoutText;
private TextArea checkoutText;
@FXML
public TextField phoneNumber;
private TextField phoneNumber;
@FXML
public GridPane itemGrid;
private GridPane itemGrid;
@FXML
public ListView<String> scannedItemsList;
private ListView<String> scannedItemsList;
@FXML
public void initialize() {
private void initialize() {
initializeSelectableItemsList();
selfCheckout = initializeSelfCheckout();
updateCartDisplay();
......@@ -54,7 +53,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleLogin() {
private void handleLogin() {
try {
selfCheckout.registerPhoneNumber(phoneNumber.getText());
updateCartDisplay();
......@@ -66,7 +65,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleCheckout() {
private void handleCheckout() {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Write receipt");
dialog.setHeaderText("Gi et navn til kvitteringen slik at du kan hente den frem igjen senere");
......@@ -99,7 +98,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleAdminActivation() {
private void handleAdminActivation() {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Admin login");
dialog.setHeaderText("Skriv inn admin-passord for denne enheten for å fortsette");
......@@ -123,7 +122,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleAdminDeactivation() {
private void handleAdminDeactivation() {
selfCheckout.deactivateAdminMode();
adminMode.visibleProperty().set(true);
backButton.visibleProperty().set(false);
......@@ -133,7 +132,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleScanReceipt() {
private void handleScanReceipt() {
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Read receipt");
dialog.setHeaderText("Skriv inn navn på kvitteringen du vil scanne inn");
......@@ -162,7 +161,7 @@ public class SelfCheckoutController {
}
@FXML
public void handleItemDeletion() {
private void handleItemDeletion() {
int selectedIndex = scannedItemsList.getSelectionModel().getSelectedIndex();
if (selectedIndex != -1) {
selfCheckout.removeFromCart(selectedIndex);
......
package selfcheckout;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.Scanner;
public class TemporaryFileReceiptHandler implements IReceiptHandler {
@Override
public SelfCheckout readReceipt(String filename, SelfCheckout selfCheckout) throws FileNotFoundException {
try (Scanner scanner = new Scanner(getFile(filename))) {
try (Scanner scanner = new Scanner(getReceiptPath(filename).toFile())) {
String phoneNumber = scanner.nextLine();
if (!phoneNumber.equals("null")) {
selfCheckout.registerPhoneNumber(phoneNumber);
......@@ -24,7 +24,7 @@ public class TemporaryFileReceiptHandler implements IReceiptHandler {
@Override
public void writeReceipt(String filename, SelfCheckout selfCheckout) throws FileNotFoundException {
try (PrintWriter writer = new PrintWriter(getFile(filename))) {
try (PrintWriter writer = new PrintWriter(getReceiptPath(filename).toFile())) {
writer.println(selfCheckout.getPhoneNumber());
for (Item item : selfCheckout.getShoppingCartItems()) {
writer.println(String.format("%s;%s;%s", item.getName(), item.getPrice(), item.getCategory()));
......@@ -33,8 +33,9 @@ public class TemporaryFileReceiptHandler implements IReceiptHandler {
}
private static File getFile(String filename) {
return new File(TemporaryFileReceiptHandler.class.getResource("receipts/").getFile() + filename + ".txt");
@Override
public Path getReceiptPath(String filename) {
return Path.of(TemporaryFileReceiptHandler.class.getResource("receipts/").getFile() + filename + ".txt");
}
}
package selfcheckout;
public class HomeFolderReceiptHandlerTest extends ReceiptHandlerTest {
@Override
protected IReceiptHandler getReceiptHandler() {
return new HomeFolderReceiptHandler();
}
}
package selfcheckout;
import static org.junit.jupiter.api.Assertions.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Iterator;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public abstract class ReceiptHandlerTest {
private static final String test_receipt_file_content = """
null
Egg, 6 stk;41.59;breakfast
Hvitost, Synnøve;90.0;diary
Leverpostei;29.99;breakfast
""";;
private static final String invalid_receipt_file_content = """
Egg, 6 stk;;breakfast
;90.0;diary
;90.0;
;;
Leverpostei;
""";;
private String adminPassword = "test123";
private String day = "mon";
protected abstract IReceiptHandler getReceiptHandler();
private SelfCheckout getPlainTestSelfCheckoutObject() {
return new SelfCheckout(day, adminPassword);
}
private SelfCheckout getFilledTestSelfCheckoutObject() {
SelfCheckout testSelfCheckoutObject = getPlainTestSelfCheckoutObject();
testSelfCheckoutObject.scanItem(new Item("Egg, 6 stk", 41.59, "breakfast"));
testSelfCheckoutObject.scanItem(new Item("Hvitost, Synnøve", 90.0, "diary"));
testSelfCheckoutObject.scanItem(new Item("Leverpostei", 29.99, "breakfast"));
return testSelfCheckoutObject;
}
@BeforeAll
public void setup() throws IOException {
Files.write(getReceiptHandler().getReceiptPath("test_receipt"), test_receipt_file_content.getBytes());
Files.write(getReceiptHandler().getReceiptPath("invalid_receipt"), invalid_receipt_file_content.getBytes());
}
@Test
public void testReadReceipt() throws IOException {
SelfCheckout expectedSelfCheckoutObject = getFilledTestSelfCheckoutObject();
SelfCheckout actualSelfCheckoutObject = getReceiptHandler().readReceipt("test_receipt",
getPlainTestSelfCheckoutObject());
assertEquals(actualSelfCheckoutObject.getPhoneNumber(), expectedSelfCheckoutObject.getPhoneNumber(),
"Phone number is not the same");
Iterator<Item> expectedIterator = expectedSelfCheckoutObject.getShoppingCartItems().iterator();
Iterator<Item> actualIterator = actualSelfCheckoutObject.getShoppingCartItems().iterator();
while (expectedIterator.hasNext()) {
try {
Item expectedItem = expectedIterator.next();
Item actualItem = actualIterator.next();
assertEquals(expectedItem, actualItem,
"Element mismatch, expected: " + expectedItem + " but got: " + actualItem);
} catch (IndexOutOfBoundsException e) {
fail("The read list does not contain the correct number of items.");
}
}
}
@Test
public void testLoadNonExistingFile() {
assertThrows(
IOException.class,
() -> getReceiptHandler().readReceipt("non_existing_file", getPlainTestSelfCheckoutObject()),
"IOException should be thrown if file does not exist!");
}
@Test
public void testReadInvalidReceipt() {
assertThrows(
IllegalArgumentException.class,
() -> getReceiptHandler().readReceipt("invalid_receipt", getPlainTestSelfCheckoutObject()),
"Only IllegalArgumentException should be thrown if content of file is invalid!");
}
@Test
public void testWriteReceipt() throws IOException {
getReceiptHandler().writeReceipt("new_receipt", getFilledTestSelfCheckoutObject());
Path expectedFile = getReceiptHandler().getReceiptPath("test_receipt");
Path actualFile = getReceiptHandler().getReceiptPath("new_receipt");
assertEquals(Files.mismatch(expectedFile, actualFile), -1,
"Contents of files are not the same");
}
@AfterAll
public void teardown() {
getReceiptHandler().getReceiptPath("new_receipt").toFile().delete();
getReceiptHandler().getReceiptPath("test_receipt").toFile().delete();
getReceiptHandler().getReceiptPath("invalid_receipt").toFile().delete();
}
}
package selfcheckout;
import static org.junit.jupiter.api.Assertions.*;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class SelfCheckoutTest {
private SelfCheckout selfCheckout;
private String adminPassword = "test123";
private String day = "mon";
@BeforeEach
public void setup() {
List<Campaign> discounts = List.of(
new Campaign("Helgerabatt på taco", 0.3, "taco", true, List.of("fri", "sat")),
new Campaign("Mandagsmat til under 200-lappen", 0.25, "dinner", false, List.of("mon")),
new Campaign("Tilbuds-Torsdag", 0.1, null, true, List.of("thu")),
new Campaign("Medlemsrabatt", 0.02, null, true,
List.of("mon", "tue", "wed", "thu", "fri", "sat", "sun")));
selfCheckout = new SelfCheckout(day, adminPassword, discounts);
}
@Test
@DisplayName("Test å registrere mobilnummer og logge inn som kunde")
public void testRegisterPhoneNumber() {
assertThrows(IllegalArgumentException.class, () -> {
selfCheckout.registerPhoneNumber("+4711234567");
}, "IllegalArgument skal utløses når mobilnummer ikke starter på +479, +474, 00474, eller 00479");
selfCheckout.registerPhoneNumber("+4741234567");
assertEquals("+4741234567", selfCheckout.getPhoneNumber());
assertThrows(IllegalStateException.class, () -> {
selfCheckout.registerPhoneNumber("+4741234567");
}, "IllegalState skal utløses når telefonnummer allerede er registrert.");
setup();
selfCheckout.registerPhoneNumber("+4791234567");
setup();
selfCheckout.registerPhoneNumber("004741234567");
setup();
selfCheckout.registerPhoneNumber("004791234567");
assertTrue(selfCheckout.isMember());
setup();
assertFalse(selfCheckout.isMember());
}
@Test
@DisplayName("Test å logge inn og ut som admin")
public void testActivateAndDeactivateAdminMde() {
assertThrows(IllegalArgumentException.class, () -> {
selfCheckout.activateAdminMode("foo");
}, "IllegalArgument skal utløses når adminpassord er feil");
selfCheckout.activateAdminMode(adminPassword);
assertThrows(IllegalStateException.class, () -> {
selfCheckout.activateAdminMode(adminPassword);
}, "IllegalState skal utløses når adminmodus allerede er aktivert.");
selfCheckout.deactivateAdminMode();
assertThrows(IllegalStateException.class, () -> {
selfCheckout.deactivateAdminMode();
}, "IllegalState skal utløses når adminmoud allerede er deaktivert.");
}
@Test
@DisplayName("Test å slette en vare fra handlekurven i forskjellige tilstander")
public void testRemoveFromCart() {
assertThrows(IllegalStateException.class, () -> {
selfCheckout.removeFromCart(0);
}, "IllegalState skal utløses når man prøver å fjerne et element fra handlekurven når admin-modus ikke er aktivert.");
selfCheckout.activateAdminMode("test123");
assertThrows(IllegalStateException.class, () -> {
selfCheckout.removeFromCart(0);
}, "IllegalState skal utløses når man prøver å fjerne et element fra handlekurven når den er tom.");
selfCheckout.scanItem(new Item("Tomat", 5, "fruit"));
selfCheckout.removeFromCart(0);
}
}
package selfcheckout;
public class TemporaryFileReceiptHandlerTest extends ReceiptHandlerTest {
@Override
protected IReceiptHandler getReceiptHandler() {
return new TemporaryFileReceiptHandler();
}
}
......@@ -5,8 +5,6 @@ import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import snakebird.Tile;
public class TileTest {
private Tile tile;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment