diff --git a/pom.xml b/pom.xml index 36eb916d13a61d55187df911e80f4a17af79d830..4f37f2aaef6c006c1cdabb857ae7787128d71766 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,13 @@ <scope>test</scope> </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-params</artifactId> + <version>5.10.0</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java index bc3a4fb0c8cf1761af66b2e63c201d3e6fa34445..3eff99fe10f391d2b5a1a4c31006cb1d0d8b270c 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java +++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/AzureDB.java @@ -1,9 +1,12 @@ package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes; +import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.CryptoException; import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.DatabaseError; +import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities.CryptoUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -14,12 +17,26 @@ public class AzureDB implements ISQLDataBase { /*this class is only here for showcasing the interchangeability of the DBMS*/ + private static String user=""; + private static String password=""; + private static String[] parts= new String[2]; + + static File encryptedFile = new File("src\\main\\resources\\database\\AzureDB_logindetails"); + private static final Logger log = LogManager.getLogger(OracleDB.class); + public static void getLoginData() throws CryptoException { + parts = CryptoUtils.decrypt(encryptedFile); + user = parts[0]; + password = parts[1]; + log.info("AzureDB_logindetails: user: " + user + " password: " + password); + } + @Override public Connection connect() throws DatabaseError { try { - String url = "jdbc:sqlserver://battlearena.database.windows.net;encrypt=true;user=battleArenaAdmin;password=krassesRPGGame23#;databaseName=battleArena;"; + getLoginData(); + String url = "jdbc:sqlserver://battlearena.database.windows.net;encrypt=true;user=" + user + ";password=" + password + ";databaseName=battleArena;"; log.info("Connecting to the database!"); Connection connection = DriverManager.getConnection(url); diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java index 09e97854b06534ac696fdc84dc89c1b5033e9474..536e604e0afb49d1a4fff850174e4b7084d215da 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java +++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/Parser.java @@ -55,7 +55,7 @@ public class Parser { if(mapName.length() < 4){ throw new ParserError("Map-Name too short! Min length is 4 characters."); } - if(mapName.length() > 40){ + if(mapName.length() > 30){ throw new ParserError("Map-Name too long! Max length is 30 characters."); } @@ -73,7 +73,7 @@ public class Parser { throw new ParserError("Map-ID length not correct. Must have length of 40 characters!"); } - Pattern pat = Pattern.compile("[^a-f0-9]", Pattern.CASE_INSENSITIVE); + Pattern pat = Pattern.compile("[^a-f0-9]"); //maybe make case-insensitive -> letters can be uppercase and still be valid hex number Matcher mat = pat.matcher(mapID); boolean result = mat.find(); if(result){ @@ -83,35 +83,55 @@ public class Parser { public static void ipAddressValid(String address) throws ParserError{ - if(!(address.length() == 15)){ - throw new ParserError("IP-Address too long. Must have length of 15 characters including block dividers (.) !"); + if(address.length() > 15){ + throw new ParserError("IP-Address too long. Must have length of 15 characters including octet dividers (.) !"); } - Pattern pat = Pattern.compile("[^0-9]"); //checks if fields only use numbers - int position; - for(int i = 0; i < 4; i++) { - position = (i*3) + (i); - Matcher mat = pat.matcher(address.substring(position, position+3)); - boolean result = mat.find(); - if(result){ - throw new ParserError("IP address does not match format xxx.xxx.xxx.xxx (numbers 0-9 for x)!"); + if(address.length() < 7){ + throw new ParserError("IP-Address too short. Must have length of 7 characters including octet dividers (.) !"); + } + + if(address.charAt(0) == '.' | address.charAt(address.length()-1) == '.'){ + throw new ParserError("IP-Address must not start nor end with octet dividers (.) !"); + } + + int counter = 0; + for(int i = 0; address.length() > i ; i++){ + if(address.charAt(i) == '.'){ + counter++; } } + if(!(counter == 3)){ + throw new ParserError("IP-Address must contain exactly 3 octet dividers (.) !"); + } - position = 0; - for(int i = 0; i < 4; i++) { - position = (i*3) + (i); - Integer.parseInt(address.substring(position, position+3)); - if(Integer.parseInt(address.substring(position, position+3)) > 255){ - throw new ParserError("IP address does not match format xxx.xxx.xxx.xxx (numbers 0-9 for x)!"); + Pattern pat = Pattern.compile("[^0-9]"); + for(int i = 0; address.length() > i ; i++){ + if(!(address.charAt(i) == '.')){ + Matcher mat = pat.matcher(address.substring(i, i+1)); + boolean result = mat.find(); + if(result){ + throw new ParserError("IP address does not consist out of numbers 0-9 and separators (.))!"); + } } } - position = 0; - for(int i = 1; i < 4; i++) { - position = (i*3) + (i); - if(!(address.charAt(position) == '.')){ - throw new ParserError("IP address does not match format xxx.xxx.xxx.xxx (wrong symbol used as separator. Must use '.')!"); + counter = 0; + int[] positions = new int[5]; + positions[0] = 0; + positions[4] = address.length(); + for(int i = 0; address.length() > i ; i++){ + if(address.charAt(i) == '.'){ + counter++; + positions[counter] = i; + } + } + for(int i = 0; 4 > i; i++){ + if(Integer.parseInt(address.substring(positions[i], positions[i+1])) > 255){ + throw new ParserError("Octets of IP-address must not exceed 255!"); + } + if(i < 3) { + positions[i + 1] = positions[i + 1] + 1; } } } @@ -139,7 +159,7 @@ public class Parser { } } - for(int i = 629; i < 647; i = i + 2){ + for(int i = 628; i < 647; i = i + 2){ if(!(Integer.parseInt(mapData.substring(i, i+1)) == 3)){ throw new ParserError("Map-Data corrupted - Bottom-Line must be border tiles!"); } diff --git a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql index 618539d398319f7af5c70582fc1ee7d4ab1080f1..97527f9a94408500c0ab3ebc11f0b9cdc72d1d79 100644 --- a/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql +++ b/src/main/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Scripts/DDL_Script_AzureDB.sql @@ -1,7 +1,10 @@ --Note: DDL to be run as admin on MsSQL (AzureDB); --Backup SQL only for CoreMaps Download + DROP TABLE coremaps; +DROP TABLE communitymaps; +DROP TABLE players; CREATE TABLE coremaps( map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex @@ -10,6 +13,25 @@ CREATE TABLE coremaps( map_height INTEGER NOT NULL, map_data VARCHAR(1682) NOT NULL); --allows for map size up to 29x29 +CREATE TABLE communitymaps( + map_id CHAR(40) NOT NULL UNIQUE, --SHA1 hash is 40 chars length in hex + map_name VARCHAR(30) NOT NULL, + map_width INTEGER NOT NULL, + map_height INTEGER NOT NULL, + map_data VARCHAR(1682) NOT NULL, --allows for map size up to 29x29 + map_downloads INTEGER NOT NULL); + +CREATE TABLE players( + player_name VARCHAR(40) NOT NULL UNIQUE, --Player name is PlayerID + player_pw VARCHAR(40) NOT NULL, + games_won INTEGER NOT NULL, + games_lost INTEGER NOT NULL, + kills INTEGER NOT NULL, + deaths INTEGER NOT NULL, + blocks_destroyed INTEGER NOT NULL, + ingame_time INTEGER NOT NULL); + + INSERT INTO coremaps (map_id, map_name, map_width, map_height, map_data) VALUES ('a593cafd1d061f0f463a2d2051bf4718aaaf5c48', 'Arena1', @@ -23,3 +45,31 @@ VALUES ('e559d8fbb53b333f5839cb3c6c0c515395afe344', 18, 18, '4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 2 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 3 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3'); + +INSERT INTO communitymaps (map_id, map_name, map_width, map_height, map_data, map_downloads) +VALUES ('a593cafd1d061f0f463a2d2051bf4718aaaf5c48', + 'Arena1', + 18, + 18, + '4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3', + 0); + +INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) +VALUES ('Player1', + 'password', + 18, + 0, + 80, + 0, + 140, + 5000); + +INSERT INTO players (player_name, player_pw, games_won, games_lost, kills, deaths, blocks_destroyed, ingame_time) +VALUES ('Player2', + 'password', + 15, + 3, + 50, + 5, + 110, + 6000); \ No newline at end of file diff --git a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java index 32497a76eefacf143535a895667a3b732c7a11c6..1cb76b2e86a4979e5ea3acd8bb90427a5a676e04 100644 --- a/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java +++ b/src/test/java/de/hdm_stuttgart/battlearena/Model/DataStorage/Classes/Utilities/ParserTest.java @@ -2,32 +2,145 @@ package de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Utilities; import de.hdm_stuttgart.battlearena.Model.DataStorage.Classes.Exceptions.ParserError; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import static org.junit.jupiter.api.Assertions.*; class ParserTest { + + @ParameterizedTest + @ValueSource(strings = {"Player1", + "Player2", + "HelloWorld"}) + void usernameValid(String test){ + assertDoesNotThrow(() -> Parser.usernameValid(test)); + } + @Test - void usernameValid() { - assertThrows(ParserError.class, () -> Parser.usernameValid("hi"), "Username too short! Min length is 4 characters."); + void usernameValidException() { + ParserError testMe = assertThrows(ParserError.class, () -> Parser.usernameValid("hi")); + assertTrue(testMe.getMessage().contains("Username too short! Min length is 4 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.usernameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi")); + assertTrue(testMe.getMessage().contains("Username too long! Max length is 40 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.usernameValid("SELECT * FROM")); + assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !")); + } + + @ParameterizedTest + @ValueSource(strings = {"pw123456", + "Passwort", + "lololol"}) + void passwordValid(String test){ + assertDoesNotThrow(() -> Parser.passwordValid(test)); } @Test - void passwordValid() { + void passwordValidException() { + ParserError testMe = assertThrows(ParserError.class, () -> Parser.passwordValid("hi")); + assertTrue(testMe.getMessage().contains("Password too short! Min length is 4 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.passwordValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi")); + assertTrue(testMe.getMessage().contains("Password too long! Max length is 40 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.passwordValid("SELECT * FROM")); + assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !")); + } + + @ParameterizedTest + @ValueSource(strings = {"Map_1", + "de_dust", + "Ziba-Tower"}) + void mapNameValid(String test){ + assertDoesNotThrow(() -> Parser.mapNameValid(test)); } @Test - void mapNameValid() { + void mapNameValidException() { + ParserError testMe = assertThrows(ParserError.class, () -> Parser.mapNameValid("hi")); + assertTrue(testMe.getMessage().contains("Map-Name too short! Min length is 4 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapNameValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi")); + assertTrue(testMe.getMessage().contains("Map-Name too long! Max length is 30 characters.")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapNameValid("SELECT * FROM")); + assertTrue(testMe.getMessage().contains("Forbidden characters used! Only user letters A-Z or numbers 0-9 or symbols '-' or '_' !")); + } + + @ParameterizedTest + @ValueSource(strings = {"a593cafd1d061f0f463a2d2051bf4718aaaf5c48", + "e559d8fbb53b333f5839cb3c6c0c515395afe344", + "a593cafd1d061f0f463a2d2051bf4718aaaf5c48"}) + void mapIDValid(String test){ + assertDoesNotThrow(() -> Parser.mapIDValid(test)); } @Test - void mapIDValid() { + void mapIDValidException() { + + ParserError testMe = assertThrows(ParserError.class, () -> Parser.mapIDValid("jiaodjidsfjoisjdiofjsiofjidosfijsodfjisdfjoi")); + assertTrue(testMe.getMessage().contains("Map-ID length not correct. Must have length of 40 characters!")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapIDValid("XYZ3cafd1d061f0f463a2d2051bf4718aaaf5c48")); + assertTrue(testMe.getMessage().contains("Forbidden characters used! Map ID only consists out of letters a-f and/or numbers 0-9!")); + } + + @ParameterizedTest + @ValueSource(strings = {"255.255.255.255", + "0.0.0.0", + "12.12.12.1"}) + void ipAddressValid(String test){ + assertDoesNotThrow(() -> Parser.ipAddressValid(test)); } @Test - void ipAddressValid() { + void ipAddressValidException() { + + ParserError testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid("255.255.255.255.255.255")); + assertTrue(testMe.getMessage().contains("IP-Address too long. Must have length of 15 characters including octet dividers (.) !")); + + testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid("0.0.0")); + assertTrue(testMe.getMessage().contains("IP-Address too short. Must have length of 7 characters including octet dividers (.) !")); + + testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid(".25.255.25.")); + assertTrue(testMe.getMessage().contains("IP-Address must not start nor end with octet dividers (.) !")); + + testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid("12.3.0.12.12")); + assertTrue(testMe.getMessage().contains("IP-Address must contain exactly 3 octet dividers (.) !")); + + testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid("255.ff.12.12")); + assertTrue(testMe.getMessage().contains("IP address does not consist out of numbers 0-9 and separators (.))!")); + + testMe = assertThrows(ParserError.class, () -> Parser.ipAddressValid("2555.800.12.12")); + assertTrue(testMe.getMessage().contains("Octets of IP-address must not exceed 255!")); + } + + @ParameterizedTest + @ValueSource(strings = {"", + "", + ""}) + void mapDataValid(String test){ + assertDoesNotThrow(() -> Parser.mapDataValid(test)); } @Test - void mapDataValid() { + void mapDataValidException() { + ParserError testMe = assertThrows(ParserError.class, () -> Parser.mapDataValid("hi")); + assertTrue(testMe.getMessage().contains("Map-Data corrupted - must have length of 647 chars including spaces!")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapDataValid("4 3 3 3 3a3a3a3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3")); + assertTrue(testMe.getMessage().contains("Map-Data corrupted - must use space every other character!")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapDataValid("8 3 6 7 9 9 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3")); + assertTrue(testMe.getMessage().contains("Map-Data corrupted - Tile number must be between 1 and 4!")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapDataValid("3 3 3 3 3 3 1 1 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3")); + assertTrue(testMe.getMessage().contains("Map-Data corrupted - Top-Line must be border tiles!")); + + testMe = assertThrows(ParserError.class, () -> Parser.mapDataValid("3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 2 1 1 1 1 1 2 2 2 1 1 1 1 2 1 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 1 2 3 4 1 1 1 2 2 4 1 3 3 3 1 1 1 3 2 2 3 4 1 1 1 2 2 4 1 1 1 1 1 1 1 3 2 1 3 4 1 1 1 2 2 4 3 3 1 4 3 3 3 3 2 1 3 4 1 1 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 1 1 3 4 1 1 1 1 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 1 1 4 3 3 1 3 3 3 3 3 1 2 3 4 1 2 1 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 2 1 1 1 2 2 2 1 1 1 1 1 1 1 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 4 1 1 1 2 2 4 3 3 1 3 3 3 3 3 2 2 3 3 3 3 3 3 3 3 1 3 1 3 3 3 3 3 3 3 1")); + assertTrue(testMe.getMessage().contains("Map-Data corrupted - Bottom-Line must be border tiles!")); + } } \ No newline at end of file