From e6f4bd9ff5fc5319ae227b8dda5443d3db1ce9b6 Mon Sep 17 00:00:00 2001
From: Rhys Evans <EvansRM17@cardiff.ac.uk>
Date: Fri, 16 Feb 2024 16:19:53 +0000
Subject: [PATCH] Further work on all testing components, creating seperate
 testing branch for correct-ness

---
 build.gradle                                  |   1 +
 .../PlacesController.java                     |   9 +-
 .../placeswithcoordinates/TownWithTrails.java |  27 +++
 .../security/SecurityConfiguration.java       |   7 +-
 .../SmartTowns/users/UserController.java      |   2 +-
 .../resources/application-test.properties     |  11 +-
 src/main/resources/application.properties     |   2 +-
 src/main/resources/data-test.sql              | 107 ++++++++++
 src/main/resources/schema-test.sql            | 139 ++++++++++++
 .../templates/towns/home/mobile-homepage.html |   1 +
 .../SmartTowns/ContainerMockMVCTests.java     |  23 ++
 .../Team5/SmartTowns/HTTPConnectionTests.java |  27 +++
 .../Team5/SmartTowns/JUnitSimpleTests.java    |  64 +++++-
 .../SmartTowns/LightweightMockMVCTests.java   | 197 ++++++++++++++++++
 14 files changed, 593 insertions(+), 24 deletions(-)
 create mode 100644 src/main/resources/data-test.sql
 create mode 100644 src/main/resources/schema-test.sql
 create mode 100644 src/test/java/Team5/SmartTowns/HTTPConnectionTests.java

diff --git a/build.gradle b/build.gradle
index d1b2500f..6190b7a7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,6 +58,7 @@ dependencies {
 // https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa
 	implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '3.2.2'
 
+	testImplementation 'org.springframework.security:spring-security-test'
 }
 
 tasks.named('bootBuildImage') {
diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java
index ec029c7b..e421f82d 100644
--- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java
+++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/PlacesController.java
@@ -69,6 +69,9 @@ public class PlacesController {
             int townIDFromTable= placeRepo.getTownIDFromName(townNamee);
             for (int i=0;i<trailslocations.size();i++){
                 int trailID = trailsRepo.getTrailIDFromTrailName(trailslocations.get(i).getTrailName());
+                System.out.println(trailslocations.get(i));
+                System.out.println(trailslocations.get(i).getTrailName());
+                System.out.println(trailID);
                 if ((trailID>100)&&(trailID<200)&&(Objects.equals(townNamee, "Caerphilly"))){
                     correctTrails.add(trailslocations.get(i));
                 }
@@ -176,8 +179,8 @@ public class PlacesController {
             break;}
         }
         ModelAndView modelAndView= new ModelAndView("fragments/trailsPageFrags :: trailsSection");
-        System.out.println(locCoords.get(0).getLocationID());
-        System.out.println(approvedLocations.get(0).getLocationID());
+//        System.out.println(locCoords.get(0).getLocationID());
+//        System.out.println(approvedLocations.get(0).getLocationID());
 //        locations[indexValue.index].getLocationTrailID()==trail.getTrailsId()}
 
 
@@ -185,7 +188,7 @@ public class PlacesController {
         List<Location> finalLocations = approvedLocations.stream()
                 .filter(loc -> Long.parseLong(loc.getLocationTrailID()) == trailslocations.get(trailIDFINAL).getTrailsId())
                         .toList();
-        System.out.println(finalLocations);
+//        System.out.println(finalLocations);
 
         modelAndView.addObject("trail", trailslocations.get(trailID));
         modelAndView.addObject("locCoords", locCoords);
diff --git a/src/main/java/Team5/SmartTowns/placeswithcoordinates/TownWithTrails.java b/src/main/java/Team5/SmartTowns/placeswithcoordinates/TownWithTrails.java
index b1049ffb..746d39e5 100644
--- a/src/main/java/Team5/SmartTowns/placeswithcoordinates/TownWithTrails.java
+++ b/src/main/java/Team5/SmartTowns/placeswithcoordinates/TownWithTrails.java
@@ -38,6 +38,33 @@ public class TownWithTrails {
         return townRightmostCoordsLong;
     }
 
+    public void setTownName(String townName) {
+        this.townName = townName;
+    }
+
+    public void setTownCentreCoordsLat(String townCentreCoordsLat) {
+        this.townCentreCoordsLat = townCentreCoordsLat;
+    }
+
+    public void setTownCentreCoordsLong(String townCentreCoordsLong) {
+        this.townCentreCoordsLong = townCentreCoordsLong;
+    }
+
+    public void setTownUppermostCoordsLat(String townUppermostCoordsLat) {
+        this.townUppermostCoordsLat = townUppermostCoordsLat;
+    }
+
+    public void setTownLowermostCoordsLat(String townLowermostCoordsLat) {
+        this.townLowermostCoordsLat = townLowermostCoordsLat;
+    }
+
+    public void setTownLeftmostCoordsLong(String townLeftmostCoordsLong) {
+        this.townLeftmostCoordsLong = townLeftmostCoordsLong;
+    }
+
+    public void setTownRightmostCoordsLong(String townRightmostCoordsLong) {
+        this.townRightmostCoordsLong = townRightmostCoordsLong;
+    }
 
     public TownWithTrails(String townName, String townCentreCoordsLat, String townCentreCoordsLong, String townUppermostCoordsLat, String townLowermostCoordsLat, String townLeftmostCoordsLong, String townRightmostCoordsLong) {
         this.townName = townName;
diff --git a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java
index 413aead4..dc30426c 100644
--- a/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java
+++ b/src/main/java/Team5/SmartTowns/security/SecurityConfiguration.java
@@ -36,10 +36,11 @@ public class SecurityConfiguration {
         http
                 .csrf(AbstractHttpConfigurer::disable)
                 .authorizeHttpRequests((requests) -> requests
-                        .requestMatchers(mvc.pattern("/user/**"), mvc.pattern("/userProfile")).authenticated()
+                        .requestMatchers(mvc.pattern("/user/**"), mvc.pattern("/userProfile"),mvc.pattern("/checkpointApproval")).authenticated()
                         .anyRequest().permitAll()
 
-                )
+                ) //all user roles, defaulkt
+
                 .formLogin((login) -> login
                         .loginPage("/login").permitAll()
                         .defaultSuccessUrl("/mobile-home")
@@ -59,6 +60,6 @@ public class SecurityConfiguration {
         JdbcUserDetailsManager manager = new JdbcUserDetailsManager(dataSource);
         return manager;
     }
-
+//.requestMatchers("/checkpointApproval").hasRole(String.valueOf(mvc.pattern("/user/**")))
 
 }
diff --git a/src/main/java/Team5/SmartTowns/users/UserController.java b/src/main/java/Team5/SmartTowns/users/UserController.java
index e9fd1bef..60638285 100644
--- a/src/main/java/Team5/SmartTowns/users/UserController.java
+++ b/src/main/java/Team5/SmartTowns/users/UserController.java
@@ -33,7 +33,7 @@ public class UserController {
         mav.addObject("user", new NewUser( "", "", ""));
         mav.addObject("error", "");
         mav.addObject("status", "");
-        System.out.println(userRepository.findUserByName("Admin").getName());
+//        System.out.println(userRepository.findUserByName("Admin").getName());
         return mav;
     }
 
diff --git a/src/main/resources/application-test.properties b/src/main/resources/application-test.properties
index 104cfa01..dff27f12 100644
--- a/src/main/resources/application-test.properties
+++ b/src/main/resources/application-test.properties
@@ -1,7 +1,4 @@
-spring.datasource.url=jdbc:h2:mem:testdb
-spring.datasource.username=sa
-spring.datasource.password=password
-spring.datasource.driver-class-name=org.h2.Driver
-spring.sql.init.platform=mock
-spring.sql.init.mode=always
-spring.autoconfigure.exclude=
+spring.datasource.url=jdbc:mariadb://localhost:3306/townstest
+spring.datasource.username=root
+spring.datasource.password=comsc
+spring.sql.init.platform=test
\ No newline at end of file
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 257b3064..b2d2a5a5 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1 @@
-spring.profiles.active=dev
\ No newline at end of file
+spring.profiles.active=test
\ No newline at end of file
diff --git a/src/main/resources/data-test.sql b/src/main/resources/data-test.sql
new file mode 100644
index 00000000..ee63ca20
--- /dev/null
+++ b/src/main/resources/data-test.sql
@@ -0,0 +1,107 @@
+delete from trails;
+insert into trails ( trailID, trailName, trailNumber, city) values ( 0101,'Caerphilly Castle Trail','0101', 'Caerphilly');
+insert into trails ( trailID, trailName, trailNumber, city) values ( 0102,'Caerphilly Pub Trail','0102', 'Caerphilly');
+insert into trails ( trailID, trailName, trailNumber, city) values ( 0103,'Caerphilly Heritage Trail','0103', 'Caerphilly');
+insert into trails ( trailID, trailName, trailNumber, city) values ( 0201,'Risca Heritage Trail','0201', 'Risca');
+insert into trails ( trailID, trailName, trailNumber, city) values ( 0301,'Penarth Esplanade Trail','0301', 'Penarth');
+
+delete from locations;
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'St Cenydd','','Location description here','Caerphilly',0101, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Castle','','Location description here','Caerphilly',0101, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Medieval Trades','','Location description here','Caerphilly',0101, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Queen''s War','','Location description here','Caerphilly',0101, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Green Lady','','Location description here','Caerphilly',0101, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Armoury','','Location description here','Caerphilly',0101, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Architecture','','Location description here','Caerphilly',0101, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( '21st Century Landmark','','Location description here','Caerphilly',0101, false);
+
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'JD Wetherspoons-Malcolm Uphill','','Location description here','Caerphilly',0102, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Caerphilly Cwtch','','Location description here','Caerphilly',0102, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Caerphilly Conservative Club','','Location description here','Caerphilly',0102, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The King''s Arms','','Location description here','Caerphilly',0102, false);
+
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Caerphilly Bus Station','','Location description here','Caerphilly',0103, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Medieval Courthouse','','Location description here','Caerphilly',0103, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ('Caerphilly Castle','','Location description here','Caerphilly',0103, false);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Ty Vaughan House','','Location description here','Caerphilly',0103, false);
+
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Risca Colliery','','Location description here','Risca',0201, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'Black Vein Colliery Disaster','','Location description here','Risca',0201, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Esplanade','','Location description here','Penarth',0301, true);
+insert into locations ( locationName , locationEmail,locationDescription,locationPlace, locationTrailID, locationApproved) values ( 'The Old Swimming Baths','','Location description here','Penarth',0301, true);
+
+
+
+
+
+DELETE FROM packs;
+INSERT INTO packs (name, description) VALUES ('Wales Football Team', 'Pack of Welsh Football Players in the National Team');
+INSERT INTO packs (name, description) VALUES ('Wales Rugby Team', 'Pack of Welsh Rugby Players in the National Team');
+INSERT INTO packs (name, description) VALUES ('Welsh Heritage', 'Pack About Welsh Heritage');
+
+DELETE FROM stickers;
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (1, 1, 'wayne_hennessey', 'Wales Football Team Player', '2');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (1, 2, 'neco_williams', 'Wales Football Team Player', '2');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (1, 3, 'joe_morrell', 'Wales Football Team Player', '2');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (1, 4, 'ethan_ampadu', 'Wales Football Team Player', '2');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (1, 5, 'connor_roberts', 'Wales Football Team Player', '2');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (2, 1, 'Taine_Basham', 'Wales Rugby Team Player', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (2, 2, 'Adam Beard', 'Wales Rugby Team Player', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (2, 3, 'Elliot Dee', 'Wales Rugby Team Player', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (2, 4, 'Corey Domachowski', 'Wales Rugby Team Player', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (2, 5, 'Ryan Elias', 'Wales Rugby Team Player', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (3, 1, 'Welsh Lady', 'Welsh Heritage', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (3, 2, 'Welsh Outline', 'Welsh Heritage', '1');
+INSERT INTO stickers (packID, stickerID, name, description, rarity) VALUES (3, 3, 'Welsh Spoon', 'Welsh Heritage', '1');
+
+
+delete from locationCoordinates;
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (2, 51.57623, -3.21910 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (3, 51.575372, -3.219186);
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (4, 51.576363, -3.220712 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (9, 51.57239, -3.21992);
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (10, 51.57230, -3.21938 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (13, 51.57168, -3.21861);
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (14, 51.57465, -3.22022 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (17, 51.61117, -3.10198 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (18, 51.61655, -3.12371 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (19, 51.43484, -3.16492 );
+insert into locationCoordinates(locationID, locationCoordsLat, locationCoordsLong) values (20, 51.43547, -3.16789 );
+
+
+delete from localauthority;
+insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) values ( 'Caerphilly County Borough Council', 'Tredomen Park','', 'Ystrad Mynach, Hengoed', '', 'CF82 7PG', 'https://www.caerphilly.gov.uk/main.aspx?lang=en-GB');
+insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) values ( 'Risca Town Council', 'Unit B, 75 Tredegar Street', '', 'Risca', '', 'NP11 6BW', 'https://www.riscatowncouncil.org.uk/');
+insert into localauthority ( localAuthorityName, address1, address2, city, county, postcode, website) values ( 'Penarth Town Council West House', 'Stanwell Road', '', 'Penarth', '', 'CF64 2YG', 'https://www.penarthtowncouncil.gov.uk/your-council/');
+
+delete from businesses;
+insert into businesses ( businessName, address1, address2, city, county, postcode, website) values ( 'Caerphilly Castle', 'Castle Street','', 'Caerphilly', '', 'CF836 1JD', 'https://cadw.gov.wales/visit/places-to-visit/caerphilly-castle');
+insert into businesses ( businessName, address1, address2, city, county, postcode, website) values ( 'Risca Museum', 'Grove Road', '', 'Risca', '', 'NP11 6GN', 'https://riscamuseum.wales/');
+insert into businesses ( businessName, address1, address2, city, county, postcode, website) values ( 'Penarth Pier Pavillion Cinema', 'Windsor Court', 'The Esplanade', 'Penarth', '', 'CF64 3AU', 'https://www.valeofglamorgan.gov.uk/en/enjoying/Coast-and-Countryside/Dog-Beach-Ban.aspx');
+
+
+delete from townsWithTrails;
+insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) values ('Caerphilly', '51.57903','-3.22075 ','51.60418','51.55093','-3.25222','-3.17696');
+insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) values ('Risca','51.61195','-3.09648','51.63039','51.59175','-3.12129','-3.06438');
+insert into townsWithTrails (townName, townCentreCoordsLat, townCentreCoordsLong, townUppermostCoordsLat, townLowermostCoordsLat, townLeftmostCoordsLong, townRightmostCoordsLong) values ('Penarth','51.43893','-3.17354','51.44878','51.41233','-3.20271','-3.16005');
+
+INSERT INTO users (username, password) VALUES ('Admin', 'admin');
+INSERT INTO users (username, password) VALUES ('Hannah', 'root');
+INSERT INTO users (username, password) VALUES ('Nigel', 'root');
+INSERT INTO users (username, password) VALUES ('Oscar', 'root');
+
+INSERT INTO authorities (username, authority) VALUES ('Admin', 'ADMIN');
+INSERT INTO authorities (username, authority) VALUES ('Hannah', 'USER');
+
+
+
+DELETE FROM stickerprogress;
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 1, 1);
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 1, 2);
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 1, 3);
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 1, 5);
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 2, 1);
+INSERT INTO stickerprogress (username, packID, stickerID) VALUES ('Admin', 2, 3);
+
+-- delete from dragonstale;
+-- insert into dragonstale(landmarkID, landmarkName, landmarkDescription, imgPath) value (1, 'A scent of...Dragon', 'The Dragon has been spotted near by, find the QR code to continue', '~/images/dragonstale/DTLM1.png');
\ No newline at end of file
diff --git a/src/main/resources/schema-test.sql b/src/main/resources/schema-test.sql
new file mode 100644
index 00000000..ccbe3b58
--- /dev/null
+++ b/src/main/resources/schema-test.sql
@@ -0,0 +1,139 @@
+/* DELETES AND RECREATES DATABASE EVERY TIME THE SYSTEM IS BOOTED*/
+DROP DATABASE IF EXISTS townstest;
+CREATE DATABASE IF NOT EXISTS townstest;
+USE townstest;
+/****************************************************************/
+
+/* DROPS ALL TABLES IF THEY EXIST (they wont but just in case) */
+drop table if exists locationCoordinates;
+drop table if exists locations;
+drop table if exists trails;
+DROP TABLE IF EXISTS stickerProgress;
+drop table if exists users;
+DROP TABLE IF EXISTS stickers;
+DROP TABLE IF EXISTS packs;
+
+
+
+
+/****************************************************************/
+
+/* CREATES ALL TABLES */
+CREATE TABLE IF NOT EXISTS trails
+(trailID varchar(128) primary key,trailName varchar(128),trailNumber varchar(128),city varchar(128)
+);
+
+
+create table if not exists locations
+(locationID bigint auto_increment primary key,
+    locationName varchar(128),
+    locationEmail varchar(128),
+    locationDescription longtext,
+    locationPlace varchar(255),
+    locationTrailID varchar(128),
+    locationApproved boolean
+);
+
+
+CREATE TABLE IF NOT EXISTS users (
+                                     username varchar(30) primary key NOT NULL,
+                                     id bigint auto_increment unique, /*DEPRECATED COLUMN, LEFT IN WHILE SOME OTHER FUNCTIONS STILL USE IT*/
+                                     email varchar(128),
+                                     password varchar(30) NOT NULL,
+                                     enabled boolean default true
+);
+
+CREATE TABLE IF NOT EXISTS authorities (
+                                           id bigint primary key auto_increment NOT NULL,
+                                           username varchar(30) NOT NULL ,
+                                           authority varchar(45) NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS packs (
+                                     id bigint auto_increment primary key,
+                                     name varchar(20) NOT NULL,
+                                     description text
+);
+
+CREATE TABLE IF NOT EXISTS stickers (
+                                        id bigint auto_increment primary key,
+                                        packID bigint NOT NULL,
+                                        FOREIGN KEY (packID) REFERENCES packs(id)
+                                            ON DELETE CASCADE
+                                            ON UPDATE RESTRICT,
+                                        stickerID bigint NOT NULL, /*STICKER ID NUMBER WITHIN ITS OWN PACK*/
+                                        name varchar(30) NOT NULL,
+                                        description text NOT NULL,
+                                        rarity tinyint
+);
+CREATE TABLE IF NOT EXISTS stickerProgress (
+                                               id bigint auto_increment primary key,
+                                               username varchar(30) NOT NULL,
+                                               FOREIGN KEY (username) REFERENCES users(username)
+                                                   ON DELETE CASCADE
+                                                   ON UPDATE RESTRICT,
+                                               packID bigint NOT NULL,
+                                               FOREIGN KEY (packID) REFERENCES packs(id)
+                                                   ON DELETE CASCADE
+                                                   ON UPDATE RESTRICT,
+                                               stickerID bigint NOT NULL,
+                                               FOREIGN KEY (stickerID) REFERENCES stickers(id)
+                                                   ON DELETE CASCADE
+                                                   ON UPDATE RESTRICT
+);
+
+create table if not exists locationCoordinates
+(
+    locationCoordID bigint auto_increment primary key,
+    locationID bigint,
+    Foreign Key (locationID) REFERENCES locations(locationID)
+        ON DELETE CASCADE
+        ON UPDATE RESTRICT,
+    locationCoordsLat DECIMAL(8,6),
+    locationCoordsLong DECIMAL(8,6)
+
+
+);
+
+
+
+create table if not exists townsWithTrails
+(
+    townID bigint auto_increment primary key,
+    townName varchar(128),
+    townCentreCoordsLat varchar(128),
+    townCentreCoordsLong varchar(128),
+    townUppermostCoordsLat varchar(128),
+    townLowermostCoordsLat varchar(128),
+    townLeftmostCoordsLong varchar(128),
+    townRightmostCoordsLong varchar(128)
+
+);
+
+
+create table if not exists localAuthority
+(
+    localAuthorityID bigint auto_increment primary key,
+    localAuthorityName varchar(250),
+    address1 varchar(250),
+    address2 varchar(250),
+    city varchar(100),
+    county varchar(75),
+    postcode varchar(15),
+    website varchar(250)
+);
+
+
+create table if not exists businesses
+(
+    businessID bigint auto_increment primary key,
+    businessName varchar(250),
+    address1 varchar(250),
+    address2 varchar(250),
+    city varchar(100),
+    county varchar(75),
+    postcode varchar(15),
+    website varchar(250)
+)
+
+
diff --git a/src/main/resources/templates/towns/home/mobile-homepage.html b/src/main/resources/templates/towns/home/mobile-homepage.html
index 480cf574..11a075e2 100644
--- a/src/main/resources/templates/towns/home/mobile-homepage.html
+++ b/src/main/resources/templates/towns/home/mobile-homepage.html
@@ -15,6 +15,7 @@
         <a class="submitLand" href="/landmarkSubmission">  <button> Submit Landmark!</button></a>
         <a th:if="${#authentication.getName().equals('Admin')}" class="reviewLand" href="/checkpointApproval">  <button> Review Landmark!</button></a>
         <p class="small-text">Choose your town and start tracking your trails!</p>
+<!--        //todo check if you can do getrole instead of getname-->
 
     </div>
 
diff --git a/src/test/java/Team5/SmartTowns/ContainerMockMVCTests.java b/src/test/java/Team5/SmartTowns/ContainerMockMVCTests.java
index 651f601e..f2d3b662 100644
--- a/src/test/java/Team5/SmartTowns/ContainerMockMVCTests.java
+++ b/src/test/java/Team5/SmartTowns/ContainerMockMVCTests.java
@@ -11,6 +11,7 @@ import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMock
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
 
 @SpringBootTest
 @AutoConfigureMockMvc
@@ -19,6 +20,7 @@ public class ContainerMockMVCTests {
     @Autowired
     private MockMvc mockMvc;
 
+//    todo have to test
     @Test
     public void a_testGreeting() throws Exception {
         this.mockMvc.perform(get("/home")).andDo(print()).andExpect(status().isOk())
@@ -30,5 +32,26 @@ public class ContainerMockMVCTests {
         this.mockMvc.perform(get("/mobile-home")).andDo(print()).andExpect(status().isOk())
                 .andExpect(content().string(containsString("Welcome to VZTA Smart Towns!")));
     }
+
+
+    @Test
+    public void a_testGreeting3() throws Exception {
+        this.mockMvc.perform(get("/towns/Caerphilly")).andDo(print()).andExpect(status().isOk())
+                .andExpect(content().string(containsString("Caerphilly Trails")));
+    }
+
+
+    @Test
+    public void a_testGreeting4() throws Exception {
+        this.mockMvc.perform(get("/mobile-home").with(SecurityMockMvcRequestPostProcessors.user("Admin").roles("ADMIN")))
+                .andDo(print())
+                .andExpect(content().string(containsString("Review Landmark!")));
+
+
+    }
+
+
+
+
 }
 
diff --git a/src/test/java/Team5/SmartTowns/HTTPConnectionTests.java b/src/test/java/Team5/SmartTowns/HTTPConnectionTests.java
new file mode 100644
index 00000000..f196bf74
--- /dev/null
+++ b/src/test/java/Team5/SmartTowns/HTTPConnectionTests.java
@@ -0,0 +1,27 @@
+package Team5.SmartTowns;
+import org.junit.jupiter.api.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.web.client.TestRestTemplate;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+public class HTTPConnectionTests {
+
+    @Value(value="${local.server.port}")
+    private int port;
+
+    @Autowired
+    private TestRestTemplate restTemplate;
+
+//todo replace values with mockDB so can differentiate from project DB
+
+    @Test
+    public void greetingShouldReturnDefaultMessage() throws Exception {
+        assertThat(this.restTemplate.getForObject("http://localhost:" + port + "/mobile-home",
+                String.class)).contains("Welcome to VZTA Smart Towns!");
+    }
+}
diff --git a/src/test/java/Team5/SmartTowns/JUnitSimpleTests.java b/src/test/java/Team5/SmartTowns/JUnitSimpleTests.java
index 679ef447..5888e245 100644
--- a/src/test/java/Team5/SmartTowns/JUnitSimpleTests.java
+++ b/src/test/java/Team5/SmartTowns/JUnitSimpleTests.java
@@ -1,11 +1,15 @@
 package Team5.SmartTowns;
 
 import Team5.SmartTowns.data.Location;
+import Team5.SmartTowns.data.Trail;
 import Team5.SmartTowns.landmarks.Landmarks;
 import Team5.SmartTowns.placeswithcoordinates.LocationsCoordinates;
 import Team5.SmartTowns.placeswithcoordinates.PlacesController;
 import Team5.SmartTowns.placeswithcoordinates.TownWithTrails;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 
@@ -15,12 +19,13 @@ import java.util.Comparator;
 import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.*;
 
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class JUnitSimpleTests {
 
     @Test
+    @Order(1)
     public void landmarksTest(){ // generic for all landmarks, trails+dragons tale
         Landmarks landmark = new Landmarks("99",1,"MockLandmark","Mock@Mock2.com",
                 "MockLandmarkDesc","MockRisca","MockImage");
@@ -50,6 +55,7 @@ public class JUnitSimpleTests {
     }
 
     @Test
+    @Order(2)
     public void locationsTest(){ //specific for trail locations
         Location location = new Location(1,"MockLocation", "Mock@Test.co.uk",
                 "MockDescription","MockCaerphilly","99",false);
@@ -85,6 +91,7 @@ public class JUnitSimpleTests {
 
 
     @Test
+    @Order(3)
     public void locationsCoordinatesTest(){
         LocationsCoordinates locCoord = new LocationsCoordinates(1,51.57756,-3.22002);
         assertEquals(locCoord.getLocationID(),1);
@@ -99,6 +106,24 @@ public class JUnitSimpleTests {
         assertEquals(-5,locCoord.getLocationCoordsLong());
     }
 
+    @Test
+    public void trailTest(){
+        Trail trail = new Trail(101L, "MockTrail", "0101");
+        assertEquals(trail.getTrailsId(),101);
+        assertEquals(trail.getTrailName(),"MockTrail");
+        assertEquals(trail.getTrailNumber(),"0101");
+        assertTrue(trail.getTrailsId()<200);
+        assertTrue(trail.getTrailsId()>100);
+
+        trail.setTrailsId(202L);
+        assertEquals(trail.getTrailsId(),202);
+        trail.setTrailName("MockChange");
+        assertEquals(trail.getTrailName(),"MockChange");
+        trail.setTrailNumber("99");
+        assertEquals(trail.getTrailNumber(),"99");
+
+    }
+
 
     @Test
     public void townWithTrailsTest(){
@@ -112,13 +137,28 @@ public class JUnitSimpleTests {
         assertEquals(townTrail.getTownLeftmostCoordsLong(),"-3.25222");
         assertEquals(townTrail.getTownRightmostCoordsLong(),"-3.17696");
 
+        townTrail.setTownName("MockChangeTown");
+        assertEquals(townTrail.getTownName(),"MockChangeTown");
+        townTrail.setTownCentreCoordsLat("50.00");
+        assertEquals(townTrail.getTownCentreCoordsLat(),"50.00");
+        townTrail.setTownCentreCoordsLong("-5.00");
+        assertEquals(townTrail.getTownCentreCoordsLong(),"-5.00");
+        townTrail.setTownUppermostCoordsLat("55.00");
+        assertEquals(townTrail.getTownUppermostCoordsLat(),"55.00");
+        townTrail.setTownLowermostCoordsLat("45.00");
+        assertEquals(townTrail.getTownLowermostCoordsLat(),"45.00");
+        townTrail.setTownLeftmostCoordsLong("-6.00");
+        assertEquals(townTrail.getTownLeftmostCoordsLong(),"-6.00");
+        townTrail.setTownRightmostCoordsLong("-4.00");
+        assertEquals(townTrail.getTownRightmostCoordsLong(),"-4.00");
+
 
-    //no setters in file add?
     }
 
     @Test
+    @Order(4)
     public void reorderingLocationCoordsListToMatchIDWithLocationListTest(){
-        List<Location> locList = new ArrayList<>();
+        List<Location> locList = new ArrayList<>(); /// trail location list, w/ ID as expected from DB output
         locList.add(new Location(1,"MockLocation", "Mock@Test.co.uk",
                 "MockDescription","MockCaerphilly","99",false));
         locList.add(new Location(2,"MockLocation2", "Mock2@Test.co.uk",
@@ -126,15 +166,21 @@ public class JUnitSimpleTests {
         locList.add(new Location(3,"MockLocation3", "Mock3@Test.co.uk",
                 "MockDescription","MockCaerphilly","99",false));
 
-        List<LocationsCoordinates> locCoordsList = new ArrayList<>();
-        locCoordsList.add(new LocationsCoordinates(3,51.57756,-3.22002));
-        locCoordsList.add(new LocationsCoordinates(1,51.57756,-3.22002));
-        locCoordsList.add(new LocationsCoordinates(2,51.57756,-3.22002));
+        List<LocationsCoordinates> locCoordsListOriginal = new ArrayList<>(); // /// trail locationCoordinates list, w/ ID as expected from DB output, locationID is foreign key.
+        locCoordsListOriginal.add(new LocationsCoordinates(3,51.57756,-3.22002));
+        locCoordsListOriginal.add(new LocationsCoordinates(1,51.57756,-3.22002));
+        locCoordsListOriginal.add(new LocationsCoordinates(2,51.57756,-3.22002));
+
+        List<LocationsCoordinates> locCoordsReorder = new ArrayList<>(); // Same list as above, repeated to allow comparison w/ original
+        locCoordsReorder.add(new LocationsCoordinates(3,51.57756,-3.22002));
+        locCoordsReorder.add(new LocationsCoordinates(1,51.57756,-3.22002));
+        locCoordsReorder.add(new LocationsCoordinates(2,51.57756,-3.22002));
 
-        List<LocationsCoordinates> locCoordsReorder=  PlacesController.reorderCoordsWRTLocations(locCoordsList);
+        PlacesController.reorderCoordsWRTLocations(locCoordsReorder); // second list reordered to be ascending locationID order to match trail location ID list.
         assertEquals(locList.get(0).getLocationID(),locCoordsReorder.get(0).getLocationID());
         assertEquals(locList.get(2).getLocationID(),locCoordsReorder.get(2).getLocationID());
         assertNotEquals(locList.get(1).getLocationID(),locCoordsReorder.get(2).getLocationID());
+        assertNotEquals(locList.get(0).getLocationID(),locCoordsListOriginal.get(0).getLocationID());
     }
 
     }
diff --git a/src/test/java/Team5/SmartTowns/LightweightMockMVCTests.java b/src/test/java/Team5/SmartTowns/LightweightMockMVCTests.java
index 7e8e21f6..21b7d839 100644
--- a/src/test/java/Team5/SmartTowns/LightweightMockMVCTests.java
+++ b/src/test/java/Team5/SmartTowns/LightweightMockMVCTests.java
@@ -1,4 +1,201 @@
 package Team5.SmartTowns;
 
+import Team5.SmartTowns.data.*;
+import Team5.SmartTowns.landmarks.LandmarksController;
+import Team5.SmartTowns.placeswithcoordinates.LocationsCoordinates;
+import Team5.SmartTowns.placeswithcoordinates.PlacesController;
+import Team5.SmartTowns.placeswithcoordinates.PlacesCoordinatesRepository;
+import Team5.SmartTowns.placeswithcoordinates.TownWithTrails;
+import Team5.SmartTowns.rewards.RewardsRepository;
+import Team5.SmartTowns.security.SecurityConfiguration;
+import Team5.SmartTowns.towns.TownController;
+import Team5.SmartTowns.towns.TownStorage;
+import Team5.SmartTowns.towns.Towns;
+import jakarta.servlet.ServletException;
+import org.junit.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration;
+import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.annotation.Import;
+import org.springframework.test.context.ActiveProfiles;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+
+import static net.bytebuddy.matcher.ElementMatchers.is;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.not;
+import static org.hamcrest.Matchers.anything;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.mockito.BDDMockito.given;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@RunWith(SpringRunner.class)
+
+//@ExtendWith(SpringExtension.class)
+@WebMvcTest({PlacesController.class, LandmarksController.class, TownController.class})
+@Import(SecurityConfiguration.class)
+@AutoConfigureTestDatabase //todo, check if this is okay - https://stackoverflow.com/questions/57958507/spring-boot-cannot-find-datasource-bean-in-junit-tests
 public class LightweightMockMVCTests {
+
+    //todo check approvalform
+
+
+    @Autowired
+    private MockMvc mockMvc;
+
+
+    @MockBean
+    private PlacesCoordinatesRepository placesRepo;
+
+    @MockBean
+    private LocationRepository locationRepo;
+
+    @MockBean
+    private TrailsRepository trailsRepo;
+
+    @MockBean
+    private RewardsRepository rewardsRepository;
+
+    @MockBean
+    private TownRepository townRepo;
+
+    @MockBean
+    TownStorage townStore;
+
+    //todo test approval site lest, post as well?
+
+
+    @Test
+    public void homeGreetingTest() throws Exception {
+        this.mockMvc.perform(get("/mobile-home")).andDo(print()).andExpect(status().isOk())
+                .andExpect(content().string(containsString("Welcome to VZTA Smart Towns!")));
+    }
+
+//    @Test
+//    public void noDBTest() throws Exception {
+//        TownWithTrails townTrail = new TownWithTrails("Caerphilly","51.57903","-3.22075",
+//                "51.60418", "51.55093", "-3.25222", "-3.17696");
+//       Trail trail = new Trail(102L, "Caerphilly Pub Trail","0101" );
+//
+//        given(this.placesRepo.getAllTownCoords()).willReturn(Arrays.asList(townTrail));
+//        given(this.trailsRepo.getAllTrails()).willReturn(Arrays.asList(trail));
+//        this.mockMvc.perform(get("/towns/Caerphilly")).andDo(print()).andExpect(status().isOk())
+//                .andExpect(content().string(containsString("MockTrail")));
+//    }
+
+
+    @Test
+    public void ensureLandmarkFormButtonShowsTest() throws Exception {
+//        Towns town = new Towns("MockTown",01,99,67,"null"); //todo this is hard coded, fix.
+//
+//        given(this.townStore.getTownList()).willReturn(Arrays.asList(town));
+//        this.mockMvc.perform(get("/mobile-home")).andExpect(status().isOk()) // check h1
+//                .andExpect(content().string(containsString("Welcome to VZTA Smart Towns!")))
+//                .andExpect(content().string(containsString("MockTown"+"99")))
+//                .andExpect(content().string(containsString("67%")));
+        this.mockMvc.perform(get("/mobile-home"))
+                .andExpect(content().string(containsString("Submit Landmark!"))); // all visitors can submit
+//                .andExpect(content().string(containsString("Review Landmark!")));
+        AssertionError thrown = assertThrows(AssertionError.class , () ->{
+            this.mockMvc.perform(get("/mobile-home")).andExpect(content().string(containsString("Review Landmark!")));;//review doesn't show for visitors
+        });
+        assertTrue(thrown.getMessage().contains("Expected: a string containing \"Review Landmark!\""));
+    }
+
+
+    @Test
+    public void checkLandmarkSubmissionFormDisplaysFieldsTest() throws Exception {
+        this.mockMvc.perform(get("/landmarkSubmission")).andExpect(status().isOk()) // check h1
+                .andExpect(content().string(containsString("Interested in joining our trails? Sign up Here!"))) //checks that all form criteria shows correctly
+                .andExpect(content().string(containsString("Business Name:"))) //input title for business name
+                .andExpect(content().string(containsString("Business name here..."))) //text box content indicator
+                .andExpect(content().string(containsString("Contact Address"))) //input title
+                .andExpect(content().string(containsString("E-mail here..."))) //text box indicator
+                .andExpect(content().string(containsString("Please Describe Your Business:")))//input title
+                .andExpect(content().string(containsString("Max 200 words please...")))//text box indicator
+                .andExpect(content().string(containsString("Your Location:")))//input title
+                .andExpect(content().string(containsString("Select Location")))//drop down default choice
+                .andExpect(content().string(containsString("Caerphilly"))) // checking all drop-down options - all hard-coded as of now todo change later?
+                .andExpect(content().string(containsString("Risca")))
+                .andExpect(content().string(containsString("Penarth")))
+                .andExpect(content().string(containsString("Trail:")))//input title
+                .andExpect(content().string(containsString("Select Trail")))//drop down default choice
+                .andExpect(content().string(containsString("(Caerphilly) Castle Trail"))) // checking all drop-down options
+                .andExpect(content().string(containsString("(Caerphilly) Pub Trail")))
+                .andExpect(content().string(containsString("(Caerphilly) Heritage Trail")))
+                .andExpect(content().string(containsString("(Risca) Heritage and Culture Trail")))
+                .andExpect(content().string(containsString("(Penarth) Esplanade Trail")))
+                .andExpect(content().string(containsString("Submit")));//button content
+    }
+
+    @Test
+    public void trailFragmentInitiallyLoadsCorrectlyForValidTrails() throws Exception {
+        Trail trail = new Trail(102L, "Mock Caerphilly Trail","0101" );
+
+        given(this.trailsRepo.getAllTrails()).willReturn(Arrays.asList(trail));
+        this.mockMvc.perform(get("/trails/Mock-Caerphilly-Trail")).andDo(print()).andExpect(status().isOk())
+                .andExpect(content().string(containsString("Mock Caerphilly Trail")));
+
+        assertThrows(ServletException.class, () ->{
+            this.mockMvc.perform(get("/trails/This-Trail-Doesnt-Exist")).andExpect(status().isNotFound());
+        });
+    }
+
+
+    @Test
+    public void trailFragmentLoadsMapForValidTrails() throws Exception { //tests trails page (which shows a list of trail-locations)
+        Trail trail = new Trail(102L, "Caerphilly Castle Trail","0102" );
+        given(this.trailsRepo.getAllTrails()).willReturn(Arrays.asList(trail));
+
+        Location location = new Location(1,"MockLocation", "Mock@Test.co.uk", //mock trail location
+                "MockDescription","MockCaerphilly","102",true);
+        given(this.locationRepo.getAllApprovedLocations()).willReturn(Arrays.asList(location));
+
+        this.mockMvc.perform(get("/trails/Caerphilly-Castle-Trail")).andDo(print()).andExpect(status().isOk())
+                .andExpect(content().string(containsString("Caerphilly Castle Trail"))) //tests that trail name loads correctly
+                .andExpect(content().string(containsString("MockLocation"))) // checks fake trail-location loads correctly
+                .andExpect(content().string(containsString("https://www.google.com/maps/dir/51.57623,-3.21910/51.575372,-3.219186/51.576363,-3.220712//@11z&output=svembed"))) //checks that href works
+                .andExpect(content().string(containsString("https://maps.google.com/maps?q=51.57623,-3.21910&output=svembed"))); //checks that current map-substitute shows
+    }
+
+
+
+    @Test
+    public void trailLocationPageTest() throws Exception { //tests individual trail-location page
+        Location location = new Location(1,"MockLocation", "Mock@Test.co.uk",
+                "MockDescription","MockCaerphilly","99",true);
+        given(this.locationRepo.getAllApprovedLocations()).willReturn(Arrays.asList(location));
+        LocationsCoordinates locCoords = new LocationsCoordinates(1,51.57756,-3.22002);
+//        LocationsCoordinates locCoords2 = new LocationsCoordinates(2,52.00,-3.10);
+        given(this.placesRepo.getAllLocationCoords()).willReturn(Arrays.asList(locCoords));
+
+
+        Trail trail = new Trail(99L, "MockLocation","0099");
+
+        String mock= "MockLocation";
+        given(this.trailsRepo.getTrailNameWithID("99")).willReturn(mock);
+        this.mockMvc.perform(get("/checkpoints/MockLocation")).andDo(print()).andExpect(status().isOk())
+                .andExpect(content().string(containsString("MockLocation"))) //checks mock-lkocation name is showing
+                .andExpect(content().string(containsString("MockDescription"))) //checks description shows
+                .andExpect(content().string(containsString("MockCaerphilly"))) //checks mock-town shows
+                .andExpect(content().string(containsString("https://maps.google.com/maps?q=51.57756,-3.22002&amp;hl=en&amp;z=20&amp;output=embed"))) //check iframe src is embedded correctly
+                .andExpect(content().string(containsString("<a href=\"/trails/MockLocation\">Return</a></H2>"))); //checks href leads back to parent trail-list
+
+    }
 }
-- 
GitLab