public async Task<bool> LoginWithToken(AuthenticationData authData)
        {
            zohoClient.Login(authData.Token);

            var progress = await dialogService.ShowProgress("Authentication", "Wait for response from server");
            progress.SetIndeterminate();

            var isSuccess = true;
            try
            {
                await
                    zohoClient.TimeTracker.TimeLog.GetAsync(authData.Id, dateTimeService.Now, dateTimeService.Now);
            }
            catch (WebException ex)
            {
                if (ex.Status != WebExceptionStatus.ProtocolError ||
                    ex.Response == null)
                {
                    throw;
                }

                var httpResponse = ex.Response as HttpWebResponse;
                if (httpResponse == null || httpResponse.StatusCode != HttpStatusCode.BadRequest)
                {
                    throw;
                }
                
                isSuccess = false;
            }

            await progress.CloseAsync();

            return isSuccess;
        }
        public void SaveAuthenticationData(AuthenticationData data)
        {
            if (!Directory.Exists(authenticationStorageFolder))
            {
                Directory.CreateDirectory(authenticationStorageFolder);
            }

            using (var file = File.Open(authenticationStorageFilePath, FileMode.Create))
            {
                var serializer = new XmlSerializer(typeof(AuthenticationData));
                serializer.Serialize(file, data);
            }
        }
        public async void LoginWithToken_WebException_Throw(
            [Frozen]Mock<IZohoClient> zoho,
            [Frozen]Mock<IDateTimeService> dateTime,
            [Frozen]Mock<IDialogService> dialog,
            [Frozen]Mock<IProgressDialogController> progressDialog,
            AuthenticationData authData,
            DateTime date,
            LoginController target)
        {
            dialog
                .Setup(x => x.ShowProgress(It.IsAny<string>(), It.IsAny<string>()))
                .ReturnsAsync(progressDialog.Object);

            zoho
                .Setup(x => x.TimeTracker.TimeLog.GetAsync(It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), "all", "all"))
                .Throws(new WebException());

            await Assert.ThrowsAsync<WebException>(async () => await target.LoginWithToken(authData));
        }
        public async void LoginWithToken_TokenIsNotValid_ReturnFalse(
            [Frozen]Mock<IZohoClient> zoho,
            [Frozen]Mock<IDateTimeService> dateTime,
            [Frozen]Mock<IDialogService> dialog,
            [Frozen]Mock<IProgressDialogController> progressDialog,
            AuthenticationData authData,
            DateTime date,
            LoginController target)
        {
            var webResponse = new Mock<HttpWebResponse>();
            webResponse.Setup(x => x.StatusCode).Returns(HttpStatusCode.BadRequest);
            dialog
                .Setup(x => x.ShowProgress(It.IsAny<string>(), It.IsAny<string>()))
                .ReturnsAsync(progressDialog.Object);

            zoho
                .Setup(x => x.TimeTracker.TimeLog.GetAsync(It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<DateTime>(), "all", "all"))
                .Throws(new WebException("", null, WebExceptionStatus.ProtocolError, webResponse.Object));

            var result = await target.LoginWithToken(authData);

            Assert.False(result);
            dialog.Verify(x => x.ShowProgress(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
            progressDialog.Verify(x => x.CloseAsync(), Times.Once);
        }
        public async void LoginWithToken_TokenIsValid_ReturnTrue(
            [Frozen]Mock<IZohoClient> zoho,
            [Frozen]Mock<IDateTimeService> dateTime,
            [Frozen]Mock<IDialogService> dialog,
            [Frozen]Mock<IProgressDialogController> progressDialog,
            AuthenticationData authData,
            DateTime date,
            LoginController target)
        {
            dateTime
                .Setup(x => x.Now)
                .Returns(date);

            dialog
                .Setup(x => x.ShowProgress(It.IsAny<string>(), It.IsAny<string>()))
                .ReturnsAsync(progressDialog.Object);

            zoho
                .Setup(x => x.TimeTracker.TimeLog.GetAsync(authData.Id, date, date, "all", "all"))
                .ReturnsAsync(new List<TimeLog>());

            var result = await target.LoginWithToken(authData);
            
            Assert.True(result);
            zoho.Verify(x => x.Login(authData.Token), Times.Once);
            zoho.Verify(x => x.TimeTracker.TimeLog.GetAsync(authData.Id, date, date, "all", "all"));
            dialog.Verify(x => x.ShowProgress(It.IsAny<string>(), It.IsAny<string>()), Times.Once);
            progressDialog.Verify(x => x.CloseAsync(), Times.Once);
        }
        public async void FillDays_TimeLogRecieved_FilledWithCorrectValues(
            [Frozen] Mock<IZohoClient> zoho,
            [Frozen] Mock<IAuthenticationStorage> auth,
            AuthenticationData authData,
            DaysService target)
        {
            var startOfTheMonth = new DateTime(2015, 07, 01);
            var middleOfTheMonth = new DateTime(2015, 07, 15);
            var endOfTheMonth = startOfTheMonth.EndOfMonth();
            
            var firstLog = new TimeLog { WorkDate = startOfTheMonth, Hours = TimeSpan.FromHours(8) };
            var secondLog1 = new TimeLog { WorkDate = middleOfTheMonth, Hours = TimeSpan.FromHours(2) };
            var secondLog2 = new TimeLog { WorkDate = middleOfTheMonth, Hours = TimeSpan.FromHours(12) };
            var thirdLog = new TimeLog { WorkDate = endOfTheMonth, Hours = TimeSpan.FromHours(10) };

            var timeLogs = new List<TimeLog>
            {
                firstLog,
                secondLog1,
                secondLog2,
                thirdLog
            };

            auth.Setup(x => x.GetAuthenticationData())
                .Returns(authData);
            var days = target.GetDays(startOfTheMonth);

            zoho.Setup(x => x.TimeTracker.TimeLog.GetAsync(authData.Id, startOfTheMonth, endOfTheMonth, "all", "all"))
                .ReturnsAsync(timeLogs);
            
            // Act
            await target.FillDaysWithTimeLogsAsync(days, startOfTheMonth);

            // Assert
            zoho.Verify(x => x.TimeTracker.TimeLog.GetAsync(authData.Id, startOfTheMonth, endOfTheMonth, "all", "all"));
            zoho.Verify(x => x.Leave.GetHolidaysAsync(authData.Id));
            
            var firstDayInCalendar = days.First(x => x.Day == startOfTheMonth.Day);
            Assert.True(firstDayInCalendar.IsActive);
            Assert.True(firstDayInCalendar.IsFilled);
            Assert.Equal(TimeSpan.FromHours(8), firstDayInCalendar.Hours);
            Assert.False(firstDayInCalendar.IsHoliday);
            
            var secondDayInCalendar = days.First(x => x.Day == middleOfTheMonth.Day);
            Assert.True(secondDayInCalendar.IsActive);
            Assert.True(secondDayInCalendar.IsFilled);
            Assert.Equal(TimeSpan.FromHours(14), secondDayInCalendar.Hours);
            Assert.False(secondDayInCalendar.IsHoliday);
            
            var secondMiddleDayInCalendar = days.First(x => x.Day == middleOfTheMonth.Day + 1);
            Assert.False(secondMiddleDayInCalendar.IsHoliday);
            
            var thirdDayInMonth = days.First(x => x.Day == endOfTheMonth.Day);
            Assert.True(thirdDayInMonth.IsActive);
            Assert.True(thirdDayInMonth.IsFilled);
            Assert.Equal(TimeSpan.FromHours(10), thirdDayInMonth.Hours);
            Assert.False(thirdDayInMonth.IsHoliday);
            Assert.Null(thirdDayInMonth.HolidayName);

            var notFilledDay = days.First(x => x.Day == 2);
            Assert.True(notFilledDay.IsActive);
            Assert.False(notFilledDay.IsFilled);
        }
        public async void FillMissingTimeLogs_SingleDay(
           [Frozen] Mock<IAuthenticationStorage> auth,
           [Frozen] Mock<IJobService> job,
           AuthenticationData authData,
           DaysService target)
        {
            var startOfTheMonth = new DateTime(2015, 07, 01);

            var notFilledDay1 = new Mock<IDayViewModel>();
            notFilledDay1.Setup(x => x.IsActive).Returns(true);
            notFilledDay1.Setup(x => x.IsFilled).Returns(false);
            notFilledDay1.Setup(x => x.Date).Returns(startOfTheMonth);

            var jobId = "1";

            job.Setup(x => x.GetJob(It.IsAny<DateTime>())).ReturnsAsync(jobId);
            auth.Setup(x => x.GetAuthenticationData()).Returns(authData);

            // Act
            await target.FillMissingTimeLogsAsync(notFilledDay1.Object);

            // Assert
            job.Verify(x => x.GetJob(startOfTheMonth), Times.Once);

            notFilledDay1.Verify(x => x.FillHoursAsync(authData.Id, jobId), Times.Once);
        }
        public async void FillMissingTimeLogs_AllNotFilledAndActiveDayFilledWithDeafultJob(
            [Frozen] Mock<IAuthenticationStorage> auth,
            [Frozen] Mock<IJobService> job,
            AuthenticationData authData,
            DaysService target)
        {
            var startOfTheMonth = new DateTime(2015, 07, 01);
            
            var days = new List<IDayViewModel>();

            var dayFromOtherMonth1 = new Mock<IDayViewModel>();
            days.Add(dayFromOtherMonth1.Object);

            var filledDay1 = new Mock<IDayViewModel>();
            filledDay1.Setup(x => x.IsActive).Returns(true);
            filledDay1.Setup(x => x.IsFilled).Returns(true);
            days.Add(filledDay1.Object);

            var notFilledDay1 = new Mock<IDayViewModel>();
            notFilledDay1.Setup(x => x.IsActive).Returns(true);
            notFilledDay1.Setup(x => x.IsFilled).Returns(false);
            notFilledDay1.Setup(x => x.Date).Returns(startOfTheMonth);
            days.Add(notFilledDay1.Object);

            var notFilledDay2 = new Mock<IDayViewModel>();
            notFilledDay2.Setup(x => x.IsActive).Returns(true);
            notFilledDay2.Setup(x => x.IsFilled).Returns(false);
            notFilledDay2.Setup(x => x.Date).Returns(startOfTheMonth.AddDays(1));
            days.Add(notFilledDay2.Object);

            var notFilledHolidayDay = new Mock<IDayViewModel>();
            notFilledHolidayDay.Setup(x => x.IsActive).Returns(true);
            notFilledHolidayDay.Setup(x => x.IsFilled).Returns(false);
            notFilledHolidayDay.Setup(x => x.IsHoliday).Returns(true);
            notFilledHolidayDay.Setup(x => x.Date).Returns(startOfTheMonth.AddDays(2));
            days.Add(notFilledHolidayDay.Object);

            var filledDay2 = new Mock<IDayViewModel>();
            filledDay2.Setup(x => x.IsActive).Returns(true);
            filledDay2.Setup(x => x.IsFilled).Returns(true);
            days.Add(filledDay2.Object);

            var dayFromOtherMonth2 = new Mock<IDayViewModel>();
            days.Add(dayFromOtherMonth2.Object);

            var jobId = "1";

            job.Setup(x => x.GetJob(It.IsAny<DateTime>())).ReturnsAsync(jobId);
            auth.Setup(x => x.GetAuthenticationData()).Returns(authData);
            
            // Act
            await target.FillMissingTimeLogsAsync(days);

            // Assert
            job.Verify(x => x.GetJob(startOfTheMonth), Times.Once);

            dayFromOtherMonth1.Verify(x => x.FillHoursAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
            filledDay1.Verify(x => x.FillHoursAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
            notFilledDay1.Verify(x => x.FillHoursAsync(authData.Id, jobId), Times.Once);
            notFilledDay2.Verify(x => x.FillHoursAsync(authData.Id, jobId), Times.Once);
            notFilledHolidayDay.Verify(x => x.FillHoursAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
            dayFromOtherMonth2.Verify(x => x.FillHoursAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
            filledDay2.Verify(x => x.FillHoursAsync(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
        }
        public async void FillDays_HolidaysRecieved_FilledWithCorrectValues(
            [Frozen] Mock<IZohoClient> zoho,
            [Frozen] Mock<IAuthenticationStorage> auth,
            AuthenticationData authData,
            DaysService target)
        {
            var startOfTheMonth = new DateTime(2015, 07, 01);
            var middleOfTheMonth = new DateTime(2015, 07, 15);
            var endOfTheMonth = startOfTheMonth.EndOfMonth();

            var singleDayyOffHoliday = new Holiday
            {
                FromDate = startOfTheMonth,
                ToDate = startOfTheMonth,
                Name = "singleHoliday",
                Remarks = DaysService.DayOffHolidayRemark
            };

            var singleDayNotOffHoliday = new Holiday
            {
                FromDate = endOfTheMonth,
                ToDate = endOfTheMonth,
                Name = "singleNoDayOffHoliday",
                Remarks = "Could be given off."
            };

            var coupleDaysHoliday = new Holiday
            {
                FromDate = middleOfTheMonth,
                ToDate = middleOfTheMonth.AddDays(1),
                Name = "twoDays",
                Remarks = DaysService.DayOffHolidayRemark
            };

            var holidays = new List<Holiday>
            {
                singleDayyOffHoliday,
                singleDayNotOffHoliday,
                coupleDaysHoliday
            };

            
            auth.Setup(x => x.GetAuthenticationData())
                .Returns(authData);
            var days = target.GetDays(startOfTheMonth);

            zoho.Setup(x => x.Leave.GetHolidaysAsync(It.IsAny<string>())).ReturnsAsync(holidays);

            // Act
            await target.FillDaysWithTimeLogsAsync(days, startOfTheMonth);

            // Assert
            zoho.Verify(x => x.Leave.GetHolidaysAsync(authData.Id));

            var firstDayInCalendar = days.First(x => x.Day == startOfTheMonth.Day);
            Assert.True(firstDayInCalendar.IsHoliday);
            Assert.Equal(singleDayyOffHoliday.Name, firstDayInCalendar.HolidayName);

            var secondDayInCalendar = days.First(x => x.Day == middleOfTheMonth.Day);
            Assert.True(secondDayInCalendar.IsHoliday);
            Assert.Equal(coupleDaysHoliday.Name, secondDayInCalendar.HolidayName);

            var secondMiddleDayInCalendar = days.First(x => x.Day == middleOfTheMonth.Day + 1);
            Assert.True(secondMiddleDayInCalendar.IsHoliday);
            Assert.Equal(coupleDaysHoliday.Name, secondMiddleDayInCalendar.HolidayName);

            var thirdDayInMonth = days.First(x => x.Day == endOfTheMonth.Day);
            Assert.False(thirdDayInMonth.IsHoliday);
            Assert.Null(thirdDayInMonth.HolidayName);
        }
 private async Task GetAndSaveUserId(AuthenticationData authData)
 {
     var progress = await dialogService.ShowProgress("Loading data from server", "Please wait");
     progress.SetIndeterminate();
     var id = await loginController.GetEmployeeId(authData.UserName);
     authData.Id = id;
     authenticationStorage.SaveAuthenticationData(authData);
     await progress.CloseAsync();
 }