commit 4b847de5d6a2b5ad2b9730b7a180be19e17f18e8
Author: A-Konig <alex-nebulae@seznam.cz>
Date:   Tue May 25 13:21:36 2021 +0200

    re #8933 Testing LoginParser

diff --git a/Server/ServerApp/DataDownload/DataDownloader.cs b/Server/ServerApp/DataDownload/DataDownloader.cs
index ebf1b98..7c033d5 100644
--- a/Server/ServerApp/DataDownload/DataDownloader.cs
+++ b/Server/ServerApp/DataDownload/DataDownloader.cs
@@ -84,6 +84,22 @@ namespace ServerApp.DataDownload
 			webClient = new WebClient();
 		}
 
+		/// <summary>
+		/// Downloads json file
+		/// </summary>
+		/// <returns> Path to file </returns>
+		public string DownloadWeatherPrediction()
+		{
+			// TODO either set this path as attribute or if parameter JsonParser needs an attribute that would be set through constructor
+			string predictionSite = "http://wttr.in/Plzen,czechia?format=j1";
+
+			DateTime now = DateTime.Now;
+			WebClient webClient = new WebClient();
+			webClient.DownloadFile(predictionSite, $"data/{now.Year}{now.Month}{now.Day}.json");
+
+			return $"data/{now.Year}{now.Month}{now.Day}.json";
+		}
+
 		/// <summary>
 		/// Creates subdirectories for all data types
 		/// TBD if we want to do it this way
diff --git a/Server/ServerApp/Parser/Parsers/LogInParser.cs b/Server/ServerApp/Parser/Parsers/LogInParser.cs
index 7247eae..a36f198 100644
--- a/Server/ServerApp/Parser/Parsers/LogInParser.cs
+++ b/Server/ServerApp/Parser/Parsers/LogInParser.cs
@@ -15,7 +15,7 @@ namespace ServerApp.Parser.Parsers
     /// Data parsed from 7am (included) to 18pm (included)
     /// </summary>
     /// <author>A. Konig</author>
-    class LogInParser
+    public class LogInParser
     {
         /// <summary> Datafile loader  </summary>
         IDataLoader loader;
@@ -99,13 +99,15 @@ namespace ServerApp.Parser.Parsers
                 // start of the day -> make an instance
                 string place = list[i].building;
                 DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, minmaxHour[0], 0, 0);
+                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
                 if (!date.Equals(lastStartDay))
                 {
                     // data for each faculty separate
                     for (int k = 0; k < TagInfo.buildings.Length; k++)
                     {
                         ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range); 
-                        loginInfo.Add(dayInfo);
+                        if (recordedAmount[k] != 0)
+                            loginInfo.Add(dayInfo);
                     }
 
                     recordedAmount = new int[TagInfo.buildings.Length];
@@ -113,7 +115,7 @@ namespace ServerApp.Parser.Parsers
                 }
 
                 // if not in allowed time window -> discard
-                if (list[i].date < startTime || list[i].date > endTime)
+                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
                     continue;
 
                 // aggregate data
@@ -142,7 +144,8 @@ namespace ServerApp.Parser.Parsers
             for (int k = 0; k < TagInfo.buildings.Length; k++)
             {
                 ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[k], recordedAmount[k], lastStartDay, range);
-                loginInfo.Add(dayInfo);
+                if (recordedAmount[k] != 0)
+                    loginInfo.Add(dayInfo);
             }
 
             return loginInfo;
@@ -192,6 +195,7 @@ namespace ServerApp.Parser.Parsers
                 // start of the day -> make an instance
                 string place = list[i].building;
                 DateTime date = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, 0, 0);
+                DateTime dateOfLessonStart = new DateTime(list[i].date.Year, list[i].date.Month, list[i].date.Day, list[i].lessonStart.Hour, list[i].lessonStart.Minute, list[i].lessonStart.Second);
 
                 // end of the day
                 if (!(date.Year == lastStartTime.Year && date.Month == lastStartTime.Month && date.Day == lastStartTime.Day))
@@ -205,7 +209,8 @@ namespace ServerApp.Parser.Parsers
                         for (int l = 0; l < TagInfo.buildings.Length; l++)
                         {
                             ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
-                            loginInfo.Add(dayInfo);
+                            if (data[k][l] != 0)
+                                loginInfo.Add(dayInfo);
                         }
 
                         data[k] = new int[TagInfo.buildings.Length];
@@ -214,7 +219,7 @@ namespace ServerApp.Parser.Parsers
                 }
 
                 // if not in allowed time window -> discard
-                if (list[i].date < startTime || list[i].date > endTime)
+                if (dateOfLessonStart < startTime || dateOfLessonStart > endTime)
                     continue;
 
                 // find index for current instance
@@ -262,7 +267,8 @@ namespace ServerApp.Parser.Parsers
                 for (int l = 0; l < TagInfo.buildings.Length; l++)
                 {
                     ActivityInfo dayInfo = new ActivityInfo(TagInfo.buildings[l], data[k][l], stTime, interval);
-                    loginInfo.Add(dayInfo);
+                    if (data[k][l] != 0)
+                        loginInfo.Add(dayInfo);
                 }
             }
 
diff --git a/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs b/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs
index 31c8058..1dafe16 100644
--- a/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs
+++ b/Server/ServerApp/WeatherPredictionParser/IJsonParser.cs
@@ -10,12 +10,12 @@ namespace ServerApp.WeatherPredictionParser
     /// <summary>
     /// Abstract class that every Json parser should inherit from
     /// </summary>
-    abstract class IJsonParser
+    public abstract class IJsonParser
     {
 
         /// <summary> Current weather </summary>
         WeatherInfo current;
-        public WeatherInfo Current { get => current; }
+        public WeatherInfo Current { get => current; set => predictions = value; }
 
         /// <summary> Prediction for today, tommorrow and day after tommorrow </summary>
         List<WeatherInfo> predictions;
diff --git a/Server/ServerApp/WeatherPredictionParser/JsonParser.cs b/Server/ServerApp/WeatherPredictionParser/JsonParser.cs
index 45b912b..5d296ec 100644
--- a/Server/ServerApp/WeatherPredictionParser/JsonParser.cs
+++ b/Server/ServerApp/WeatherPredictionParser/JsonParser.cs
@@ -18,15 +18,8 @@ namespace ServerApp.WeatherPredictionParser
     /// Class representing a parser for json prediction data
     /// </summary>
     /// <author>A. Konig</author>
-    class JsonParser : IJsonParser
+    public class JsonParser : IJsonParser
     {
-        /// <summary> Current weather </summary>
-        WeatherInfo current;
-        public new WeatherInfo Current { get => current; }
-        /// <summary> Prediction for today, tommorrow and day after tommorrow </summary>
-        List<WeatherInfo> predictions;
-        public new List<WeatherInfo> Predictions { get => predictions; set => predictions = value; }
-
         /// <summary> Data loader </summary>
         DataDownloader loader;
         /// <summary> Currently parsed day </summary>
@@ -55,12 +48,12 @@ namespace ServerApp.WeatherPredictionParser
             // TODO ask DataDownloader for download said file and return path to it
             
             // get file
-            string file = DownloadWeatherPrediction();
+            string file = loader.DownloadWeatherPrediction();
             DateTime now = DateTime.Now;
             Console.WriteLine(File.Exists(file));
 
-            current = new WeatherInfo();
-            predictions = new List<WeatherInfo>();
+            Current = new WeatherInfo();
+            Predictions = new List<WeatherInfo>();
 
             if (!File.Exists(file))
                 return;
@@ -84,7 +77,7 @@ namespace ServerApp.WeatherPredictionParser
                     case "current_condition":
                         {
                             ArrayEnumerator currentWeather = weatherP.Current.Value.EnumerateArray();
-                            current = ParseCurrentWeather(currentWeather);
+                            Current = ParseCurrentWeather(currentWeather);
 
                             break;
                         }
@@ -110,25 +103,11 @@ namespace ServerApp.WeatherPredictionParser
         /// </summary>
         private void TestConsoleOutput()
         {
-            Console.WriteLine(current);
-            foreach (WeatherInfo w in predictions)
+            Console.WriteLine(Current);
+            foreach (WeatherInfo w in Predictions)
                 Console.WriteLine(w);
         }
 
-        // TODO move to data loader
-        /// <summary>
-        /// Downloads json file
-        /// </summary>
-        /// <returns> Path to file </returns>
-        private string DownloadWeatherPrediction()
-        {
-            DateTime now = DateTime.Now;
-            WebClient webClient = new WebClient();
-            webClient.DownloadFile("http://wttr.in/Plzen,czechia?format=j1", $"data/{now.Year}{now.Month}{now.Day}.json");
-
-            return $"data/{now.Year}{now.Month}{now.Day}.json";
-        }
-
         /// <summary>
         /// Change data in a way that they now reflect sunrise and sunset times
         /// If current time under sunrise or over sunset -> WeatherConditions is Dark
@@ -137,14 +116,14 @@ namespace ServerApp.WeatherPredictionParser
         private void EncompassSunRiseSetTimes()
         {
             // change current weather
-            if ((current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
-                current.condition = WeatherConditions.Dark;
+            if ((Current.startTime.TimeOfDay > sunsetTime.TimeOfDay) || (Current.startTime.TimeOfDay < sunriseTime.TimeOfDay))
+                Current.condition = WeatherConditions.Dark;
 
             // change prediction
-            for (int i = 0; i < predictions.Count - 1; i++)
+            for (int i = 0; i < Predictions.Count - 1; i++)
             {
-                WeatherInfo w = predictions[i];
-                WeatherInfo wNext = predictions[i + 1];
+                WeatherInfo w = Predictions[i];
+                WeatherInfo wNext = Predictions[i + 1];
 
                 // if wNext time < than w time then it is prediction from the next day -> add 24 to correctly calculate timespan
                 int timespan = wNext.startTime.Hour - w.startTime.Hour;
@@ -178,7 +157,7 @@ namespace ServerApp.WeatherPredictionParser
             }
 
             // last prediction
-            WeatherInfo wLast = predictions[predictions.Count - 1];
+            WeatherInfo wLast = Predictions[Predictions.Count - 1];
             TimeSpan endTimeW = new TimeSpan(24, 0, 0);
             int timespanLast = endTimeW.Hours - wLast.startTime.Hour;
             wLast.intervalLength = timespanLast;
@@ -338,8 +317,7 @@ namespace ServerApp.WeatherPredictionParser
                 }
 
                 // Console.WriteLine(weather.ToString());
-                predictions.Add(weather);
-
+                Predictions.Add(weather);
             }
 
         }
diff --git a/Server/TestProject/ParserTests/TestingParser.cs b/Server/TestProject/ParserTests/TestingParser.cs
index c6d86bf..dfaec2b 100644
--- a/Server/TestProject/ParserTests/TestingParser.cs
+++ b/Server/TestProject/ParserTests/TestingParser.cs
@@ -5,6 +5,8 @@ using System.Collections.Generic;
 using ServerApp.Parser.OutputInfo;
 using Moq;
 using ServerApp.Parser.InputData;
+using ServerApp.WeatherPredictionParser;
+using ServerApp.DataDownload;
 
 // 1h
 // 0.5h to edit parsers 
@@ -440,6 +442,8 @@ namespace TestProject
 
         #endregion
 
+        // -------------------------------- JIS PARSER -----------------------------------------
+
         #region Jis parser
 
         #region Parse days
@@ -703,9 +707,339 @@ namespace TestProject
             Assert.AreEqual(new ActivityInfo("MENZA", 5, new DateTime(2000, 1, 1, 11, 0, 0), 2), retVal[1]);
             Assert.AreEqual(new ActivityInfo("MENZA", 1, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[2]);
         }
+        #endregion
+
+        #endregion
+
+        // -------------------------------- LOGIN PARSER ----------------------------------------
+
+        #region Login parser
+
+        #region Parse days
+        [TestMethod]
+        public void ParseLoginDayOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayOneFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 6, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 16, 0, 0));
+
+            Assert.AreEqual(2, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayTwo()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayTwoFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 6, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 19, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 3, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 3, 0, 0, 0));
+
+            Assert.AreEqual(4, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 4, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FAV", 6, new DateTime(2000, 1, 1, 7, 0, 0), 18 - 7), retVal[1]);
+
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FEL", 5, new DateTime(2000, 1, 2, 7, 0, 0), 18 - 7), retVal[3]);
+        }
+
+
+        [TestMethod]
+        public void ParseLoginDayNone()
+        {
+            TagInfo.CreateDictionaries();
 
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "UC", "Učebna", "UC-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 16, 00, 0), new DateTime(2000, 1, 1, 16, 5, 0), "UC", "Učebna", "UC-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 3, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EU", "Učebna", "EU-108", "uc233p02-fav"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 6, new DateTime(2000, 1, 1, 12, 20, 0), new DateTime(2000, 1, 1, 12, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 7, new DateTime(2000, 1, 1, 17, 00, 0), new DateTime(2000, 1, 1, 17, 5, 0), "EU", "Učebna", "EU-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLogInFileAsDays", path, new DateTime(2000, 1, 1), new DateTime(2000, 1, 1, 9, 0, 0));
+            
+            Assert.AreEqual(0, retVal.Count);
+        }
         #endregion
 
+        #region Parse hours
+        [TestMethod]
+        public void ParseLoginHourlyOne()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginDayHourlyMultiple()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginHourlyFiltering()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 9, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 10, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 13, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 14, 00, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1), new DateTime(2001, 1, 1));
+
+            Assert.AreEqual(5, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 2, 17, 0, 0), 2), retVal[4]);
+        }
+
+        [TestMethod]
+        public void ParseLoginHourlyNone()
+        {
+            TagInfo.CreateDictionaries();
+
+            string path = "";
+            List<LogInInstance> data = new List<LogInInstance>();
+            // "01.06.2019 00:00:00"; 2; 4; "10:15"; "11:00"; "LS"; "Učebna"; "LS-234"; "ls233p02-fdu"
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 3, new DateTime(2000, 1, 1, 5, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 1, 4, new DateTime(2000, 1, 1, 9, 15, 0), new DateTime(2000, 1, 1, 11, 0, 0), "EL", "Učebna", "UC-108", "uc233p02-fav"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 19, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 1, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 19, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "UC", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 2, 6, new DateTime(2000, 1, 1, 18, 0, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+            data.Add(new LogInInstance(new DateTime(2000, 1, 2, 0, 0, 0), 5, 7, new DateTime(2000, 1, 1, 18, 20, 0), new DateTime(2000, 1, 1, 10, 5, 0), "LS", "Učebna", "LS-108", "ls233p02-fdu"));
+
+            Mock<IDataLoader> dl = new Mock<IDataLoader>();
+            dl.Setup(m => m.LoadLoginFile(path)).Returns(data);
+
+            LogInParser target = new LogInParser(dl.Object);
+            PrivateObject obj = new PrivateObject(target);
+
+            List<ActivityInfo> retVal = (List<ActivityInfo>)obj.Invoke("ProcessOneLoginFileAsIntervals", path, 2, new DateTime(2000, 1, 1, 10, 0, 0), new DateTime(2000, 1, 2, 10, 0, 0));
+
+            Assert.AreEqual(0, retVal.Count);
+        }
+        #endregion
+
+        #endregion
+
+        // -------------------------------- JSON PARSER -----------------------------------------
+
+        #region Json parser
+
+        [TestMethod]
+        public void JsonParser()
+        {
+            // TODO needs rewrite after DataDownloader has correct download method
+            TagInfo.CreateDictionaries();
+
+            string data = "";
+
+            Mock<DataDownloader> dl = new Mock<DataDownloader>();
+            dl.Setup(m => m.DownloadWeatherPrediction()).Returns(data);
+
+            JsonParser target = new JsonParser(dl.Object);
+
+            target.ParsePrediction();
+            WeatherInfo current = target.Current;
+            List<WeatherInfo> retVal = target.Predictions;
+
+            Assert.AreEqual(8, retVal.Count);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[0]);
+            Assert.AreEqual(new ActivityInfo("FEL", 1, new DateTime(2000, 1, 1, 9, 0, 0), 2), retVal[1]);
+            Assert.AreEqual(new ActivityInfo("FDU", 2, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[2]);
+            Assert.AreEqual(new ActivityInfo("FAV", 5, new DateTime(2000, 1, 1, 13, 0, 0), 2), retVal[3]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[4]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[5]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[6]);
+            Assert.AreEqual(new ActivityInfo("FDU", 7, new DateTime(2000, 1, 1, 17, 0, 0), 2), retVal[7]);
+        }
+
         #endregion
     }
 }
