From 1ecacb734c6f261f40aa70cee39d5b931f6f9cd9 Mon Sep 17 00:00:00 2001
From: "Appleton, Joseph Dr (Comp Sci & Elec Eng)" <j.appleton@surrey.ac.uk>
Date: Thu, 27 Feb 2025 07:42:34 +0000
Subject: [PATCH] initial commit

---
 .classpath                                    |  57 ++++++++++++
 .project                                      |  34 +++++++
 .settings/org.eclipse.jdt.apt.core.prefs      |   2 +
 .settings/org.eclipse.jdt.core.prefs          |   9 ++
 .settings/org.eclipse.m2e.core.prefs          |   4 +
 pom.xml                                       |  24 +++++
 .../travelagency/CurrencyConverter.java       |  36 +++++++
 .../com1028/travelagency/CurrencyService.java |  13 +++
 .../travelagency/ExcursionService.java        |  15 +++
 .../com/com1028/travelagency/TripAdvisor.java |  78 ++++++++++++++++
 .../com1028/travelagency/TripDatabase.java    |  16 ++++
 .../com/com1028/travelagency/TripManager.java |  48 ++++++++++
 .../com1028/travelagency/WeatherService.java  |  18 ++++
 .../travelagency/CurrencyConverterTest.java   |  46 +++++++++
 .../com1028/travelagency/TripAdvisorTest.java |  74 +++++++++++++++
 .../com1028/travelagency/TripManagerTest.java |  88 ++++++++++++++++++
 .../travelagency/CurrencyConverter.class      | Bin 0 -> 964 bytes
 .../travelagency/CurrencyService.class        | Bin 0 -> 204 bytes
 .../travelagency/ExcursionService.class       | Bin 0 -> 280 bytes
 .../com1028/travelagency/TripAdvisor.class    | Bin 0 -> 2755 bytes
 .../com1028/travelagency/TripDatabase.class   | Bin 0 -> 320 bytes
 .../com1028/travelagency/TripManager.class    | Bin 0 -> 1006 bytes
 .../com1028/travelagency/WeatherService.class | Bin 0 -> 328 bytes
 .../travelagency/CurrencyConverterTest.class  | Bin 0 -> 2022 bytes
 .../travelagency/TripAdvisorTest.class        | Bin 0 -> 2984 bytes
 .../travelagency/TripManagerTest.class        | Bin 0 -> 3163 bytes
 26 files changed, 562 insertions(+)
 create mode 100644 .classpath
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.jdt.apt.core.prefs
 create mode 100644 .settings/org.eclipse.jdt.core.prefs
 create mode 100644 .settings/org.eclipse.m2e.core.prefs
 create mode 100644 pom.xml
 create mode 100644 src/main/java/com/com1028/travelagency/CurrencyConverter.java
 create mode 100644 src/main/java/com/com1028/travelagency/CurrencyService.java
 create mode 100644 src/main/java/com/com1028/travelagency/ExcursionService.java
 create mode 100644 src/main/java/com/com1028/travelagency/TripAdvisor.java
 create mode 100644 src/main/java/com/com1028/travelagency/TripDatabase.java
 create mode 100644 src/main/java/com/com1028/travelagency/TripManager.java
 create mode 100644 src/main/java/com/com1028/travelagency/WeatherService.java
 create mode 100644 src/test/java/com/com1028/travelagency/CurrencyConverterTest.java
 create mode 100644 src/test/java/com/com1028/travelagency/TripAdvisorTest.java
 create mode 100644 src/test/java/com/com1028/travelagency/TripManagerTest.java
 create mode 100644 target/classes/com/com1028/travelagency/CurrencyConverter.class
 create mode 100644 target/classes/com/com1028/travelagency/CurrencyService.class
 create mode 100644 target/classes/com/com1028/travelagency/ExcursionService.class
 create mode 100644 target/classes/com/com1028/travelagency/TripAdvisor.class
 create mode 100644 target/classes/com/com1028/travelagency/TripDatabase.class
 create mode 100644 target/classes/com/com1028/travelagency/TripManager.class
 create mode 100644 target/classes/com/com1028/travelagency/WeatherService.class
 create mode 100644 target/test-classes/com/com1028/travelagency/CurrencyConverterTest.class
 create mode 100644 target/test-classes/com/com1028/travelagency/TripAdvisorTest.class
 create mode 100644 target/test-classes/com/com1028/travelagency/TripManagerTest.class

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..653dfd7
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="target/generated-sources/annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..7feca82
--- /dev/null
+++ b/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>TravelAgency</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+	<filteredResources>
+		<filter>
+			<id>1740642098171</id>
+			<name></name>
+			<type>30</type>
+			<matcher>
+				<id>org.eclipse.core.resources.regexFilterMatcher</id>
+				<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>
diff --git a/.settings/org.eclipse.jdt.apt.core.prefs b/.settings/org.eclipse.jdt.apt.core.prefs
new file mode 100644
index 0000000..d4313d4
--- /dev/null
+++ b/.settings/org.eclipse.jdt.apt.core.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.apt.aptEnabled=false
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3a7f4f9
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,9 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=disabled
+org.eclipse.jdt.core.compiler.release=disabled
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..14b697b
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..f747836
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,24 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.com1028.lab7</groupId>
+	<artifactId>TravelAgency</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<name>MyAgency</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<version>4.13.1</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.mockito</groupId>
+			<artifactId>mockito-core</artifactId>
+			<version>4.8.0</version>
+		</dependency>				
+	</dependencies>
+
+</project>
\ No newline at end of file
diff --git a/src/main/java/com/com1028/travelagency/CurrencyConverter.java b/src/main/java/com/com1028/travelagency/CurrencyConverter.java
new file mode 100644
index 0000000..9e72bf4
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/CurrencyConverter.java
@@ -0,0 +1,36 @@
+package com.com1028.travelagency;
+
+/**
+ * 
+ * Defines the properties and behaviour for a Currency Converter class
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public class CurrencyConverter {
+	CurrencyService service;
+	
+	public CurrencyConverter() {
+		this.service = null;
+	}
+	
+	// The CurrencyService is a dependency passed via a setter method
+	public void setCurrencyService(CurrencyService service) {
+		this.service = service;
+	}
+	
+	/**
+	 * Retrieve the new currency amount given a amount in currency 1 to be converted to currency 2
+	 *
+	 * @return currency amount
+	 */	
+	public double convertCurrency(double amount, String currency1, String currency2) {
+		double newCurrencyAmount;
+		
+		// Call the currency service to get the exchange rate between currencies 1 & 2
+		double exchangeRate = service.getExchangeRate(currency1, currency2);
+		newCurrencyAmount = amount * exchangeRate;
+		return newCurrencyAmount;
+		
+	}
+}
diff --git a/src/main/java/com/com1028/travelagency/CurrencyService.java b/src/main/java/com/com1028/travelagency/CurrencyService.java
new file mode 100644
index 0000000..5908a21
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/CurrencyService.java
@@ -0,0 +1,13 @@
+package com.com1028.travelagency;
+
+/**
+ * 
+ * Interface that defines the behaviour of a Currency Service
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public interface CurrencyService {
+	// This method returns the exchange rate given the names of two currencies 
+	public double getExchangeRate(String currency1, String currency2);
+}
diff --git a/src/main/java/com/com1028/travelagency/ExcursionService.java b/src/main/java/com/com1028/travelagency/ExcursionService.java
new file mode 100644
index 0000000..a3c20bd
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/ExcursionService.java
@@ -0,0 +1,15 @@
+package com.com1028.travelagency;
+
+import java.util.List;
+
+/**
+ * 
+ * Interface that defines the behaviour of an Excursion Service
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public interface ExcursionService {
+	// This method returns the list of excursions that are provided for a given city
+	public List<String> excursionList(String city);
+}
diff --git a/src/main/java/com/com1028/travelagency/TripAdvisor.java b/src/main/java/com/com1028/travelagency/TripAdvisor.java
new file mode 100644
index 0000000..8652b37
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/TripAdvisor.java
@@ -0,0 +1,78 @@
+package com.com1028.travelagency;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ * Defines the properties and behaviour for a Trip Advisor class
+ * It provides weather info and available excursions for a given city
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public class TripAdvisor {
+	ExcursionService excursionService;
+	WeatherService weatherService;
+	
+	public TripAdvisor() {
+		excursionService = null;
+		weatherService = null;
+	}
+	
+	// The excursionService is a dependency passed via a setter method
+	public void setExcursionService(ExcursionService excursionService) {
+		this.excursionService = excursionService;
+	}
+	
+	public void setWeatherService(WeatherService weatherService) {
+		this.weatherService = weatherService;
+	}
+	
+	/**
+	 * Retrieve the excursions of a given type offered in a specified city 
+	 * e.g. beach, island, historic
+	 * 
+	 * @return list of excursions
+	 */		
+	public List<String> getExcursionList(String city, String type){
+		List<String> allExcursions = new ArrayList<String>();
+		
+		// Call the excursion service to get all the excursions listed for a particular city
+		allExcursions = excursionService.excursionList(city);
+		
+		List<String> chosenExcursions = new ArrayList<String>();
+		for(String excursion: allExcursions) {
+			//Checking to see if the excursion is of the type specifies e.g. beach
+			if (excursion.toLowerCase().contains(type.toLowerCase())){
+				chosenExcursions.add(excursion);
+			}
+		}
+		return chosenExcursions;
+	}
+
+	/**
+	 * Retrieve the weather information for specified city in a specific month
+	 * 
+	 * @return the weather info as a string
+	 */	
+	public String weatherInfo(String city, Integer month) {
+		Integer temp = weatherService.predictedAverageTemperature(city, month);
+		Double rainprob = weatherService.predictedRainProbability(city, month);
+		
+		String weather = null;
+		
+		if (temp >= 21 && rainprob >= 0.5) {
+			weather = "Warm and Rainy";
+		} else if (temp >= 21 && rainprob < 0.5) {
+			weather = "Warm and Dry";
+		} else if (temp < 21 && rainprob < 0.5){
+			weather = "Cold and Dry";
+		} else {
+			weather = "Cold and Rainy";
+		}
+		
+		return weather;
+	}	
+}
+
diff --git a/src/main/java/com/com1028/travelagency/TripDatabase.java b/src/main/java/com/com1028/travelagency/TripDatabase.java
new file mode 100644
index 0000000..083a27e
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/TripDatabase.java
@@ -0,0 +1,16 @@
+package com.com1028.travelagency;
+
+import java.util.List;
+/**
+ * 
+ * Interface that defines the behaviour of a Trip Database Service
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public interface TripDatabase {
+	// This method returns  the total cost of a trip for a given customer ID
+	public double totalTripCost(String CustomerID);
+	// This method returns  the list of cities to be visited in order by the customer given the ID
+	public List<String> cityItinerary(String CustomerID);
+}
diff --git a/src/main/java/com/com1028/travelagency/TripManager.java b/src/main/java/com/com1028/travelagency/TripManager.java
new file mode 100644
index 0000000..219e72b
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/TripManager.java
@@ -0,0 +1,48 @@
+package com.com1028.travelagency;
+
+import java.util.List;
+/**
+ * 
+ * Defines the properties and behaviour for TripManager
+ * to apply a discount to the total trip cost and get the itinerary
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+
+public class TripManager {
+	
+	private TripDatabase tripDB;
+	
+	/**
+	 * Constructor sets the trip database
+	 * TripDatabase dependency is passed via the constructor
+	 * @param tripDB 
+	 * 			The database with details on Customers' Trips
+	 */
+
+	public TripManager(TripDatabase tripDB) {
+		this.tripDB = tripDB;
+	}
+	
+	/**
+	 * Retrieve the cost of a customers trip after applying a discount
+	 * 
+	 * @return discounted cost
+	 */	
+	public double applyDiscount(int percentageDiscount, String CustomerID) {
+		double cost = tripDB.totalTripCost(CustomerID);
+		return cost - (cost *percentageDiscount/100);
+		//return 1600.00;
+	}
+	
+	/**
+	 * Retrieve the itinerary of a customer's trip given the customer id
+	 * 
+	 * @return a list of places a traveller will visit in order
+	 */		
+	public List<String> getItinerary(String CustomerID){
+		return tripDB.cityItinerary(CustomerID);
+	}
+
+}
diff --git a/src/main/java/com/com1028/travelagency/WeatherService.java b/src/main/java/com/com1028/travelagency/WeatherService.java
new file mode 100644
index 0000000..2615cf6
--- /dev/null
+++ b/src/main/java/com/com1028/travelagency/WeatherService.java
@@ -0,0 +1,18 @@
+package com.com1028.travelagency;
+
+/**
+ * 
+ * Interface that defines the behaviour of a Weather Service
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public interface WeatherService {
+	// This method returns the predicted average temperature for a given city in a given month
+	// The month is expressed as a digit e.g. September = 9
+	public Integer predictedAverageTemperature(String city, Integer month);
+	
+	// This method returns the predicted rain probability for a given city in a given month
+	// The month is expressed as a digit e.g. September = 9	
+	public Double predictedRainProbability(String city, Integer month);
+}
diff --git a/src/test/java/com/com1028/travelagency/CurrencyConverterTest.java b/src/test/java/com/com1028/travelagency/CurrencyConverterTest.java
new file mode 100644
index 0000000..9bd69eb
--- /dev/null
+++ b/src/test/java/com/com1028/travelagency/CurrencyConverterTest.java
@@ -0,0 +1,46 @@
+package com.com1028.travelagency;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/**
+ * 
+ * Tests that the CurencyConverter class is returning the correct exchange amount
+ * Annotations are used in these tests
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class CurrencyConverterTest {
+
+	// @InjectMocks annotation is used to create and inject the mock object
+	@InjectMocks
+	CurrencyConverter converter = new CurrencyConverter();
+
+	// @Mock annotation is used to create the mock object to be injected
+	@Mock
+	CurrencyService service;
+
+	@Test
+	public void testConvertCurrency() {
+		// Method chain to return 1.12 as the exchange rate between pound and euro
+		when(service.getExchangeRate("pound", "euro")).thenReturn(1.12);
+		assertEquals(1120.0, converter.convertCurrency(1000.0, "pound", "euro"), 0);
+		verify(service).getExchangeRate("pound", "euro");
+	}
+
+	@Test(expected = RuntimeException.class)
+	public void testConvertCurrencyException() {
+
+		doThrow(new RuntimeException("ExchangeRate not implemented")).when(service.getExchangeRate("pound", "euro"));
+		assertEquals(1120.0, converter.convertCurrency(1000.0, "pound", "euro"), 0);
+		verify(service).getExchangeRate("pound", "euro");
+	}
+}
\ No newline at end of file
diff --git a/src/test/java/com/com1028/travelagency/TripAdvisorTest.java b/src/test/java/com/com1028/travelagency/TripAdvisorTest.java
new file mode 100644
index 0000000..155b32f
--- /dev/null
+++ b/src/test/java/com/com1028/travelagency/TripAdvisorTest.java
@@ -0,0 +1,74 @@
+package com.com1028.travelagency;
+
+import static org.junit.Assert.*;
+
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InOrder;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/**
+ * 
+ * Tests that the TripAdvisor class is retrieving an excursion list of the required type
+ * as well as retrieving the correct weather information
+ * Annotations are used in these tests
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class TripAdvisorTest {
+
+	@InjectMocks
+	TripAdvisor tripAdvisor = new TripAdvisor();
+	
+	// @Mock annotation is used to create the mock object to be injected
+	@Mock
+	ExcursionService excursionService;
+	
+	@Mock
+	WeatherService weatherService;
+	
+	@Test
+	public void testExcursionList() {
+		String city = "Chania";
+		List<String> excursions = new ArrayList<String>();
+		excursions.add("Samaria Gorge");
+		excursions.add("Santorini Island");
+		excursions.add("Elafonisi Beach");
+		excursions.add("Gavdos Island");
+		excursions.add("Preveli Beach");
+		
+		String type = "beach";
+		List<String> beachExcursions = new ArrayList<String>();
+		beachExcursions.add("Elafonisi Beach");
+		beachExcursions.add("Preveli Beach");
+		
+		// Method chain to return the above lsit of excursions when a city "Chania" is specified
+		when(excursionService.excursionList(city)).thenReturn(excursions);
+		assertEquals(beachExcursions, tripAdvisor.getExcursionList(city, type));
+		verify(excursionService).excursionList(city);
+	}
+	
+	
+	@Test
+	public void testWeatherInfo() {
+		String city = "Chania";
+		Integer month = 9;
+		InOrder inOrder = inOrder(weatherService);
+		
+		when(weatherService.predictedAverageTemperature(city, month)).thenReturn(27);
+		when(weatherService.predictedRainProbability(city, month)).thenReturn(0.15);
+		assertEquals("Warm and Dry", tripAdvisor.weatherInfo(city, month));
+		
+		inOrder.verify(weatherService).predictedAverageTemperature(city, month);
+	    inOrder.verify(weatherService).predictedRainProbability(city, month);
+	}
+}
diff --git a/src/test/java/com/com1028/travelagency/TripManagerTest.java b/src/test/java/com/com1028/travelagency/TripManagerTest.java
new file mode 100644
index 0000000..b499a39
--- /dev/null
+++ b/src/test/java/com/com1028/travelagency/TripManagerTest.java
@@ -0,0 +1,88 @@
+package com.com1028.travelagency;
+
+import static org.junit.Assert.*;
+
+
+
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * 
+ * Tests that the TripManager class is calculating the discount correctly
+ * Also a Spy on an itinerary object is created and tested
+ * Static methods of Mockito are used
+ * 
+ * @author Mariam Cirovic
+ * 
+ */
+public class TripManagerTest {
+
+	TripManager manager;
+	
+	// Mock the Trip Database class
+	TripDatabase db = mock(TripDatabase.class);
+	
+	@Before
+	public void setUp() {
+		manager = new TripManager(db);
+	}
+	
+	@Test
+	public void testApplyDiscount() {
+		
+		// Method chain (stub) to state that the customerID c11 should return the value 2000.00
+		when(db.totalTripCost("c11")).thenReturn(2000.0);
+		assertEquals(1600.0, manager.applyDiscount(20, "c11"), 0);
+		verify(db).totalTripCost("c11");	
+		
+		when(db.totalTripCost("c20")).thenReturn(5000.0);
+		assertEquals(4000.0, manager.applyDiscount(20, "c20"), 0);
+		//assertEquals(4000.0, manager.applyDiscount(20, "c20"), 0);
+		verify(db).totalTripCost("c20");
+		
+		//check if method is called once
+	     verify(db, times(1)).totalTripCost("c20");
+	      
+	     //verify that method was never called on a mock
+	     verify(db, never()).cityItinerary("c11");
+	}
+
+	@Test
+	public void testItinerarySpy() {
+		List<String> itinerary = new ArrayList<String>();
+		
+		itinerary.add("London");
+		itinerary.add("Paris");
+		itinerary.add("Rome");		
+		
+		// Create a spy to spy on the real instance itinerary
+		List<String> itinerarySpy = spy(itinerary);
+		
+		assertEquals("London", itinerarySpy.get(0));
+		
+		// This is a stub - it states that return "Madrid" in position 1 instead of "Paris"
+		// You can use a spy to do a partial mock
+		doReturn("Madrid").when(itinerarySpy).get(1);
+		assertEquals("Madrid", itinerarySpy.get(1));
+		
+		assertEquals("Rome", itinerarySpy.get(2));
+		
+		System.out.println("Number of cities: " + itinerarySpy.size());
+		
+		// Add another city to the spy object
+		itinerarySpy.add("Athens");
+		
+		System.out.println("Number of cities (spy): " + itinerarySpy.size());
+		// The size of itinerary is unchanged - the object was only added to the spy
+		// The spy has all the behaviour of the real object so it is mostly used to 
+		// to explore legacy code that does not come with a clearly defined interface
+		System.out.println("Number of cities (original): " + itinerary.size());
+				
+	}
+}
diff --git a/target/classes/com/com1028/travelagency/CurrencyConverter.class b/target/classes/com/com1028/travelagency/CurrencyConverter.class
new file mode 100644
index 0000000000000000000000000000000000000000..7cea9855d473619b5f958ed96ff4e8cd87a7cebb
GIT binary patch
literal 964
zcma)4+iuf95Iq|^F>&3dH{z6A2ra5(D5ez;RIMVR1fC+02<p3IR;f#3OO6vjd=x?g
zA$Z^e_$b7&V~19G2(orHGdpw6nHm57^Ya&gC%CVnAYgmp$l*DBeDu_bBX=r??m!0K
zN2fiBqQq#2!Bj@Ej5MeM>lg0Sb%t&*a9;H<q!$ZlV;N0-PZF%V6s<SQJrO9K`hg#}
z1Qe@zCZM*%w^E0K6$2Wsl_9Wdpoo${rRxXs<z&>C(HplvB++I!^xWZ@8~KT!1=aZ6
z9}7HOE@IviWo(XRoVS{Z6F9JzgXEng;w#>4NI8&zWp%p$M%9ZWKNy@WMw*=!nAp)!
zW6A#x&%h1bB<VoL&p&wQ+=YDY#vIGOwaBm-X?8e#cN9(nE>F-Yd)cZFlgTcqzLanz
zuo1}jd7IBN5JO&(q4&Z`<jEI)vZ`vHJRka_gaHjMSmBQ-c(`TW3T<wlcbVQP3hA3}
ze}`_1Z!o?vTEH6bwX|{-Dy=dq`~YK?jdg6$V<XtgkXo!NFjlf3TtU&(=oZ<xQ-ta)
zD??y@s*5Ay`}GX#6FC!gru`Mh!H)U^RRzb|eocFKT&xv8^Xan0ItAWkc_SrgrEQvX
k0u#4zo4|y_9n{mNOy<`~vQ4kS*J9e@Jz5$wcT@bmzf(ro^8f$<

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/CurrencyService.class b/target/classes/com/com1028/travelagency/CurrencyService.class
new file mode 100644
index 0000000000000000000000000000000000000000..42d43a4580095e287502b35a11637edb808b2216
GIT binary patch
literal 204
zcmX^0Z`VEs1_l!bPId++Mh1=K{9Jt?HZ(A@&@U-UEKAKvOi#^AuGDufEh+*rf>Vpi
zGLuu;8CVz@1hNv#67_Qu^V0SGld@8iOBfmW(^E@aE0QySVyQuiC8>-I>KZ->Wx*vy
znR)5fm?D}kj0{}C`K3k4scxA$Ky4yu7V3cvVPj-qWMBrmmw|y1Xg@0h8;Hfg4kVcv
FH~@)jIO6~S

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/ExcursionService.class b/target/classes/com/com1028/travelagency/ExcursionService.class
new file mode 100644
index 0000000000000000000000000000000000000000..d741173f5f4d551a101883a70138ba7b50956110
GIT binary patch
literal 280
zcmX^0Z`VEs1_l!bZgvJHMh4B~{9Jt?HZ(A@&@U-UEKAKvOi#^AuGDv}NG>fZ&dkpX
zPAw|SOipEIU}0ns$Vx0r)Xz!GOV{^L%1TWxVPxP<g(>vOEC%vbG<*<>f=h}r^U|#~
zAws1knK}9(Ro09QoWYstd5I;ZMX8Jo7DQ;V!8FwlXbe|yerZv1s#|6b&>T^8H|v31
i!p6wJ$iNKrGXn!7&<m^#Y(PFckjKQp0c3H4SzG`H8&FLE

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/TripAdvisor.class b/target/classes/com/com1028/travelagency/TripAdvisor.class
new file mode 100644
index 0000000000000000000000000000000000000000..0490fec3db6176cdb408c861ffa0a4a4495a1f67
GIT binary patch
literal 2755
zcmbVNTUQfT6#h;w3?u_a6lz4R7b@Wz@6`mMT(rdoyg;F-wVh1HFq+K7$%M!+>Gh?3
z@wHv6#YMYTSD*XbAJAW-{mx{_g-BN`i#a)GpS{1c_qX>x=g(Ka{tn<0wiE;e26elb
z<ahqug{w)|(Kd~OmNzVYE4kvBrJ3BOS+*SoA%WNvZBt7YG%KIHoqb~HE=9(3z2cNj
z+gdi9O;a}nMl<^Y-q@p@7U-!On!8~*b@So<&DUB~Y1}bsTBbWC5KIiO3WVnDoDo3~
z-72~e>4Lxk6=8J9*+CTwIw{GRma$YRW({XW%NFQxZ^qWO!m8$&a_tL4?uJ<wIJ>_$
zP3+K>LuJF=8=k;KVt@O++G!cWLBh0#DKPdgAg#I{L@eLrNyaQQOIH$^M(UPb$F%b4
zcFAx}RB_EhQra=9u4OZCX>P?KO}E|(WU~F7skDN3$(ZMociN2OXj}5g2u`3oiqjZW
za7JMGKUb29_i$FAyIzj9zz5&pb6c2EBru|2n8ny|N!qIz#h5^+=^Bpa+KxbfqS<=E
zm#3qcz&Qm;)=~pucUQ%ETwrlp#&f3P@Ge4A8<CGoE!|a1Q3MxpMaBELDiC$;j9oRH
zIjzi8w1W5vmFg)KX-v{(-L_oKv{=Cd%@oXSXza9S6}GpL9=<OlpHeZ657<IlE+^2}
ztX*qzPj3RVD&{aRploR6B`*{<-F?QTo9>ouqP7a-p1W0|yWLu$P_K5n6l*WEn7(0`
z4XatJtDZ~p-rAx>_1koC57ZmWjUFt!n*MZAEBR(o|JGTs9@_%fnuBg{j|Iy$@`jW4
zQ|~3t*NWmERun7?4DDO0tu3nJ6R^(*N{*2;b=SzvY_hoW#)?ra$tv?&E%pB$+I3QT
z^r?z<Ff~W&humW=+;QxzmNg4ry51t>dAq{vF&)7}JW}u(@2W<|{nJ%^jxS`xSnjG;
zs4(@ck%b7d$SKfUO1y@q!oXuzch19Z*vxlK|IH_gf1P;3zFgCs;z`ZQos@xWb)q1k
z)@Ab!B^D)fb|L3!d6E+C>JraRAY5c$Z1C=Bs@7fRWVtd4bl>42C9>68)qec!0Ka$y
zBFlEg(T$s?d`4nT55k0`2B-M!1Q|nsA73FEj(mf>74KF=xF6-}1~mkK4~)EoIwF2S
zj~rq@Q4~Ng$6kc|@es`pqX&IBM2T86qoj{3wh7+xA*X05kL?&4C0qk3;z{Fl=ctF!
zU(@mtsP8!{h;jt+H(@n-Rl_<?ixc}`$zUbcQ4H{$WArD0<1%Cs<4oat{WqLge~FVz
zBR`{ObO)ybSn@@w(D)991X3L@kcfBeU|ir2Tug=I;cZ+V<F}1#U!yx7iidY_J%BZ-
zG$ZiM>%Zcm9|<1v$UE&ZKE!c^ZjRB7ao&_k%;Fp}oUd{v$(-^sv|guToq4%Q=jkLq
z<SamhyZ8tT%;_;)$1To6w2k9q?uLm4CSX@<v97g9ttIXqN8mMvpePUuE_(k7g%_~G
z#{+{r=r-<fl<f4=M3zgHti(pgc5pWc$&fc+3nCQ~sqpwV9>n^-M}IuD4ec=UUw(^7
zubB$Jz;xT*SKo2(soXnL+xwwm=j|2cp3-YedL?&3kGl&jF<_G8b;dc(xM%p9&EhiO
zf<?@ej~g%<eUS{6$c;-b8eCTETvqE`R`CoDSyJ&7WzK@ceMGwoLq3KF*z~xRd>usS
W6|O3Hs31$W1_pv;r^<~0p8o@aj+{XN

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/TripDatabase.class b/target/classes/com/com1028/travelagency/TripDatabase.class
new file mode 100644
index 0000000000000000000000000000000000000000..06d87d429c7166e3654941568988e69a5d0ea3ab
GIT binary patch
literal 320
zcma)2L23d)5UerLjV3~J@CORXB@;sqf*}`05CjkF2ijp+Mkcc|+bitXJoo?~71FDR
z1d@Y?hU%iKyQ`01`vZVCbQ3fb1}6X1Qp1<mk>*G{>nXFrRC*QNc1lcZDr|ylh5HTd
zNP7yIUamLRutJw}CSNNjc_Dr8aq%NcIl7RIpQfTSj;lGlU?as!q5q%mY%SS&y>JDO
z722uG0&y9w!sr6a``_&!GNzN}Wi)o?yv%v{o$I;2wxytOB|iZg60?aG>bMDRgm2d@
KI)ZLb=<XZ9a9L9T

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/TripManager.class b/target/classes/com/com1028/travelagency/TripManager.class
new file mode 100644
index 0000000000000000000000000000000000000000..dfabac1693ba88abd46a3429cba7da2500864648
GIT binary patch
literal 1006
zcma)4+iuf95IyUp35lIHls1%BT-v5>oD>X*hf1jmB2lHF01v4m@whRT+2Yudy{?om
z;Bx>8gvtXSz(*lwH-ScKRmH1ad1hzM%sI2a|NQ&~;2HMwFc_+CG<0Y`dHnRikug8>
z0`7aEJ9bWDF?!8Ivf@0l4CPaP#+`tNzVmi)>ba63Cn=`=l3}lVElitBKH!Phq?AJu
z3VFm(ug#fb_ZhOS=)G4&2Bw8PEQU<Y?iawYXkh_4hNZ3uy*KG_;Ke6=5O@sB-N@xZ
zpT|PkQ)gCw5DCNX^`)n*soN4Cje>DoByN<3M7UDxbT4G+5&h6_+HDgRtmSc=VP`HK
zEZo65q030}K<V6y5<*|CT?L+d@s8$2A8{IavFnABW^&OJ>o62sX(FSc7kAo<`K1;~
zL06YxbZ_~d>`2lp=JA+bz*SWz5UCV_(-ny%DGEK|hg_yHX?rk7%HicMj+#oSngttG
zV($t$p6R35i&A2DEY$SMGq3NFqJvH1pV2B9YUK2nAx|DR=q!+R41*R>tpA|h_>R(7
zvJ5QIxu`SOkR{y<SVx(Bl}R*iVwo(;)2NKlZeeALIiNZVDz^R&rTufP8hB;f8=pR|
zU?cKB)6E3GsIj(SVq0U^sgkPj54(c9xJQ`EcOMTZ+N8CKEzMyYRr2g;v|Y{RIoXPf
gsp>Y)v1j0mzE)&%8tCB+3G;s;Q^P9~bsgXM3x^5dA^-pY

literal 0
HcmV?d00001

diff --git a/target/classes/com/com1028/travelagency/WeatherService.class b/target/classes/com/com1028/travelagency/WeatherService.class
new file mode 100644
index 0000000000000000000000000000000000000000..16bb022f9642f5bb74396dc6bf02cd53ffb1fa13
GIT binary patch
literal 328
zcmb7=&1wQc5QM8ubQ5zCauIxhB$td44>5ZR1VIoYZXoB`u~|pPS!re$e6<|%0C}k3
z>?J?o#Y02$K^0Z?_5JY)V2rB-Ey9f{w<_MlaP+8x=$f4_*qgn2XC2lo8B1*qCpahc
zHoDfzX<w+<e8VOX20P)EHGx;pHA|Gf@pc!VPze*BZs)&}EQs|*`iIPX;DRN+JHiP4
zAM2&Iej#P9bL(u_6DFtozLZt&I3;wmvJ%5n>tev`|1IyEv>gKBEN%p}V(B(IXv!zJ
Kh=g$2aC8rc8)CZv

literal 0
HcmV?d00001

diff --git a/target/test-classes/com/com1028/travelagency/CurrencyConverterTest.class b/target/test-classes/com/com1028/travelagency/CurrencyConverterTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..fa53b37104fdaeec0dd829caa20241d6ee196a53
GIT binary patch
literal 2022
zcmbtU-*XdH6#h18vu(PzC8R0^p+JEoLbqTCktnn@MT&t+Qc^1Z+H7yrt;ufP>=t;^
z7ax3b{8N}wo66|;?7yNf{sWHR-E5N$7R!teclX|N&pG!y=X~e<{`b$n0+_+NikN~a
z(`o2j7pE^>(LLAL7ImX0Z1age@4K$t%sckBa6REJi>9ZdPr>M>v2Eye!>;K|)lFe~
z3I@$REd}R`FYhz2;7G~0J*y!qR@181#hh(Bp5a-J-Q-=-acg?RF~6`pM_;t%V|RFJ
z(oSs(ciS?Bg51FmmfN~COZB*v&L~X0YuT1}O+h@9ttjZ5ch*D_ag1uv@QR8QA9?wp
zk~oCXK`0p0(2s<Ik)mabyMCj}BpQq{Kw%p7is4%F918oq4U0if9~@3kO^E-n$J&I#
zy}GeZL8zNPL(^sP@)FY<8U~RZzzGHYTaIt94d5gr7QX8Y;WW;um{gECFxW7m8qVSz
z1FQ*e;jy_vN{Eu-F~D<~VwWXl&$aAY{@;>pA&D&BRFUgpRl)I@6%FTcfpy+C>b_W7
zXF4;5Y{W-fE1!gpiz=p>g(z8MWl0(hm+%(jd$b{J1y`e}+T6`&dkE3={A!h8^(DLJ
z@Lvwk`NZ|V{`ls2>)xM3cpLAixT0V(`reBSHC&Ydk{$t+gy*|<V)py5*?~Y}_Pg0&
zBMCFBVGcK#%CM8VWz1v>k*NPOmj&EZvA|qPWbMMwHQ6VghWBwxfo24!g)e=hPNpR?
zg+d`)kr}+L;R6&YVy|24PZXTpH&xx5hS^haY#;8C3t~(5uz~^cc#B;t)~Fc?BW(JP
zVqV2PR<P@TdBb%c$>vZ|RxsYZc;0dV_vt#yz6nl{39GSH7Y$+a<s?d2k)8ZNawq~K
z%w;<RA8B}qkIA<+CwN=I<;=r~atF|h7!y!MxcMP`iqBPiMpXL}B-E44WWtkW$9GL}
z(~@Ihe6Q*~4L&7<=VhdwUEj8at1}lXmbbwP&>wUO%hto@HU+{~xP704fEF~&<0MBx
zoaBpfaYpf^awq=-0VO#jBC;XM;yiO0@;l7ajo=K7=5{cWdxk@+J2?C!(ocC8!>jxb
z2mZ&<ha(ul7+#}Hqcv^tI%VK~oc>~+myZTkz*m$=y~W%QIF>q|n%KpuI9kZGFqOs(
zH@mnT!%7-?YNXS6Pb&R{>%%R~OPdxJf5YjH<%2G$6yX4;aDt<529vmjGZA2m9bk7l
zz=jCrDA!#ROF`t{hUm(Dzu?2w_%oDNQ_DN3lv`MR9`G(c`9C;waya4|=U@pJA~?$-
U&KL|v6GJsfp+stOt(g%200Suv!T<mO

literal 0
HcmV?d00001

diff --git a/target/test-classes/com/com1028/travelagency/TripAdvisorTest.class b/target/test-classes/com/com1028/travelagency/TripAdvisorTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..ab96c7e9aa16c4145e937bbb506026a8b47c3ed0
GIT binary patch
literal 2984
zcmbVOZBr9h6n-`d29i}`L@H7(wp4jFidK<W6#+3CKnX(C+IEv%lEq{fHyae~o7KK*
ze@tgu#X9Xc({KGP{SBQycXtz)2s2D!lD&KHIp?19oadaAzyJOHPXNd9a~J^yJvp<S
z;OFR(q2YvWX)B_n6@-ynP0U&P@@RfVub9@HsMukI6vURa6)jQHj6z~2yCib9f~fsk
zPQk(SR_rAebj(%_TQ7@wy`pDJV$?89TeEf3sPHUpT7^W}%-z;)Gm$dnMN@pMP%kF#
z<*HVNf*E10=sBUFfAc#h8iZ*ezRtKb%gr5kg=QCpRkzu@xy^-jqEy~?S~qn2jDlcK
z@4SN0n3)$51QA!U1Fd1SDd^q`DiQ2Lyafv0QqhEM3R=^;A*QS4tgz-Zg5)@#(@OK2
zrOS73Gh`QaqSm*$%MGcd&pU0Vw2n?%uP~D_2brZRgGtDYC!6sOqZ=z~hOUKiK*262
z{Z(5pB}OevTa|hdbRpi1ZUx&jT3LG5HOcgeC=Q}0j6($XwU$&+(ThHUrRDPqcK4(k
zDV6NK(ToAQlhF*@w1{n2szS=;n{k+!Oq8@m(;#cQ&I>J9Y{n7ZJgKeZ%}QNvh+9`I
zK`z&&jw@)&N(Bk<2^B4fL@|t!Fit7x-84OQh&*PfNa8fD*IDR7*X<7@!-_Bp$zC@y
z2Q4X;jNlB;g>jZR`uQy>NS>=0#d)&lZc!KtM*IfdQlmk?TE(trv%DuUV-!q2Gv0eL
zig8>BV}h*PioA+Rd2fXDH)e%hwG7F_l!{BZ%p?><BTY{DUGrk~C2{lUr!W)7G;K<^
zT$+tmD#9WouHdQyRde1Z?o_oB`FzNKj|YM8o*F3g64s20Ib0)ISA?Z6uCfnppzI~Y
z*S%N>p`310KJK&ZML<mIS*AO&#&lBGUR`EUwmQ73GljD4Y13b(l=4coyTQomH?KWI
zr&?uodVMBkESeE~hHMxb>-KfEqzqdWgry<}7E*XcD^<nJA}{Yr`6Knjl9Km}DpYKj
zfE88fSfZM4%vgD0v3>O1^f^;QcOB(Yt}Gc=f)PfUIoh;v)^|x2CYBX+E?Xk6=WLN5
zWuiD|=0tg!3$l(luH*ch#Ht0dQE<{DB2fX`*q-_&vzl&PvCOQN)k{v6Px)D~wHwCG
zDm!g*+u6U4Ie!t{!~HNw8Q&~)g=8ik$d)$lchNJ@j4#OW1<fjVv6Xd=TdT6nzEbfu
z9&(6!^G7CI!T)g63nq$3$b|8@p~ZNKV+$;shF#>TFV!_%>G_7)W*ubAs+AKLbUA|B
z8ivVX$w&ozeZ#}58iueEobU^}T_m5I9CFHE2mX%awg9jFUAo4xLk%h>ae!P6@<)pN
za1!z@%$0mL^9k9!eS1-7kHl`+3-X-<nBOr<oToK~&sg7c?Cg7qUDuyu_it$bg?j<)
z;r9;bzD|U&pIV*h;GXL0U@zan_1ioN)V<lqJ=#`=sMEyt)A;`MOLWolyHf-4_g>)r
z02T(~{k6qlZIP%gj=GEZv1w0lB-9a#dvaWP=Y7B816ny5z#2Xrc!4q6?FezVy?^i-
zF0LUhCDt(e3d644f{ZKZ#C3)~gF`onK19)vHVj}N205P(Bf<Y+9OYCS;@CKbY5p+$
z2q#%i!?=%Ac!CiJhvRO19u7hLh<Pj!k0>5e{yH&9;wo-%FGxEVag%!?e9U{>dFD#p
z;>ta{#WMw;Y=kBL;aP}!kBMchWeuNBh5kVBdXNE%%o+;Qa?wu=ZU-e8u}+G(fYc7|
zI0tR0uHmkG691fM?fnDK@Fk%dl!7ntO#rV@@+>X9u}LcqhAuY_l5@aWMt6>@QQ|sA
z)W&fc6O42c24jANl!H~D>wg`qhaOffcz|#59Z}dre06+JYXST~y8+@U86G7nKk@S<
Hho}Dm^1KnJ

literal 0
HcmV?d00001

diff --git a/target/test-classes/com/com1028/travelagency/TripManagerTest.class b/target/test-classes/com/com1028/travelagency/TripManagerTest.class
new file mode 100644
index 0000000000000000000000000000000000000000..5f4f8f0c86e398198ef902f387bb66cda482f9f5
GIT binary patch
literal 3163
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

literal 0
HcmV?d00001

-- 
GitLab