public async Task ShouldAddTimeSheet()
        {
            var command = new CreateTimeSheetCommand();

            using (var httpTest = new HttpTest())
            {
                string response = File.ReadAllText("Data/timepro-web-timesheet-added.html");
                httpTest.RespondWith(response, 200);

                string empID   = "JEK";
                string date    = "2019-05-06";
                var    request = new CreateTimeSheetRequest("http://tnturl.xyz", "token-1")
                {
                    EmpID         = empID,
                    DateCreated   = date + "+10",
                    ClientID      = "SSW",
                    ProjectID     = "LEAVE",
                    CategoryID    = "LNWD",
                    LocationID    = "SSW",
                    BillableID    = "W",
                    ClientEmpRate = 245m,
                    ClientTaxRate = 0.1m,
                    Comment       = "SSW (SSW) - Labour Day public holiday (QLD & SI only)"
                };

                var result = await command.Execute(request);

                result.Should().NotBeNull();
                result.IsSuccessful.Should().BeTrue();

                httpTest.CallLog.Should().HaveCount(1, "should not fail");
                var httpRequest = httpTest.CallLog.First();
                httpRequest.Request.RequestUri.ToString().Should().Be($"http://tnturl.xyz/Timesheet/{empID}/{date}/Add");

                httpTest
                .ShouldHaveCalled($"http://tnturl.xyz/Timesheet/{empID}/{date}/Add")
                .WithBasicAuth("token-1", string.Empty)
                .WithVerb(HttpMethod.Post)
                .WithRequestBody(
                    "EmpTime.TimeID=0&EmpTime.IsAutomaticComments=False&EmpTime.EmpID=JEK" +
                    "&EmpTime.TfsComments=&EmpTime.DateCreated=06%2F05%2F2019&EmpTime.ClientID=SSW&EmpTime.ProjectID=LEAVE" +
                    "&UseIteration=false&EmpTime.CategoryID=LNWD&EmpTime.LocationID=SSW" +
                    "&EmpTime.TimeStart=8%3A00+AM&EmpTime.TimeEnd=5%3A00+PM&EmpTime.TimeLess=1&TotalTimeTextBox=8" +
                    "&EmpTime.BillableID=W&EmpTime.IsBillingTypeOverridden=false&EmpTime.SellPrice=245" +
                    "&EmpTime.SalesTaxPct=0.1&EmpCreated=&EmpUpdated=&SaveType=Add" +
                    "&Note=SSW+(SSW)+-+Labour+Day+public+holiday+(QLD+%26+SI+only)")
                .Times(1);
            }
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string tenantUrl      = req.Query["tenantUrl"];
            string empID          = req.Query["empID"];
            string date           = req.Query["date"];
            string token          = req.Query["token"];
            string githubUsername = req.Query["githubUsername"];
            string githubToken    = req.Query["githubToken"];
            bool   isDebug        = GetTruthy(req.Query["debug"]);
            bool   isDryRun       = GetTruthy(req.Query["dryRun"]);

            if (string.IsNullOrEmpty(date))
            {
                date = DateTime.Today.ToString("yyyy-MM-dd") + "+10";
            }

            date = date?.Replace(" ", "+");

            var collectDataRequest = new CollectDataRequest(tenantUrl, empID, date, token, githubUsername, githubToken);
            var collectedData      = await _collectDataQuery.Execute(collectDataRequest);

            var timesheet = await _suggestTimeSheetQuery.Execute(collectedData.ToSuggestTimeSheetRequest());

            if (timesheet.ClientID == null || timesheet.CategoryID == null || timesheet.ProjectID == null)
            {
                var model = new ModelStateDictionary();
                if (timesheet.ClientID == null)
                {
                    model.AddModelError(nameof(timesheet.ClientID), "No client was found");
                }

                if (timesheet.ProjectID == null)
                {
                    model.AddModelError(nameof(timesheet.ProjectID), "No project was found");
                }

                if (timesheet.CategoryID == null)
                {
                    model.AddModelError(nameof(timesheet.CategoryID), "No category was found");
                }

                return(new BadRequestObjectResult(model));
            }

            var clientRate = await _getClientRateQuery.Execute(new GetClientRateRequest(tenantUrl, empID, timesheet.ClientID, token));

            if (clientRate?.ClientEmpRate == null || clientRate?.ClientTaxRate == null)
            {
                var model = new ModelStateDictionary();
                if (clientRate?.ClientEmpRate == null)
                {
                    model.AddModelError(nameof(clientRate.ClientEmpRate), "Client employee rate is not available");
                }

                if (clientRate?.ClientTaxRate == null)
                {
                    model.AddModelError(nameof(clientRate.ClientTaxRate), "Client tax rate is not available");
                }

                return(new BadRequestObjectResult(model));
            }

            var result = new AutoCreateTimeSheetModel
            {
                SuggestTimeSheet = timesheet,
                ClientRate       = clientRate
            };

            if (isDebug)
            {
                result.Debug = collectedData;
            }

            if (!timesheet.AlreadyHasTimesheet && !isDryRun)
            {
                try
                {
                    var request = new CreateTimeSheetRequest(tenantUrl, timesheet, clientRate.ClientEmpRate.Value, clientRate.ClientTaxRate.Value, token);
                    var success = await _createTimeSheetCommand.Execute(request);

                    result.IsCreated = success.IsSuccessful;
                }
                catch (Exception e)
                {
                    log.LogError(e, "Something went wrong when adding a timesheet");
                }
            }

            return(new JsonResult(result));
        }