public async Task Book_EmployeeNotOnShiftButShiftNotAvailable_ViewDataWarning()
        {
            // Arrange
            IStringLocalizer <ShiftsController> stringLocalizer = Substitute.For <IStringLocalizer <ShiftsController> >();

            stringLocalizer.GetString("NoShiftsAvailable").Returns(new LocalizedString("NoShiftsAvailable", "There are no shifts available."));

            IRepository <Library.Models.Shift> shiftRepository = Substitute.For <IRepository <Library.Models.Shift> >();
            DateTime         now             = DateTime.Now;
            ILocationService locationService = Substitute.For <ILocationService>();

            locationService.Get().Returns(new[] { new Library.Models.Location {
                                                      id = "1", Name = "Contoso"
                                                  } });
            locationService.GetByName("Contoso").Returns(new Library.Models.Location {
                id = "1", Name = "Contoso"
            });

            ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService, stringLocalizer: stringLocalizer);

            controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
            ShiftViewModel viewModel = new ShiftViewModel {
                LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till"
            };

            // Act
            IActionResult result = await controller.Book(viewModel);

            // Assert
            ViewResult viewResult = Assert.IsType <ViewResult>(result);

            Assert.Equal(stringLocalizer["NoShiftsAvailable"], viewResult.ViewData["ValidationError"]);
        }
        public async Task Book_EmployeeNotOnShift_BooksOnShift()
        {
            // Arrange
            IRepository <Library.Models.Shift> shiftRepository = Substitute.For <IRepository <Library.Models.Shift> >();
            DateTime now = DateTime.Now;

            shiftRepository.Get(
                "SELECT * FROM c WHERE c.LocationId = @locationId AND c.StartDateTime = @start AND c.EndDateTime = @end AND c.WorkType = @workType AND c.Allocated = false",
                Arg.Any <IDictionary <string, object> >(), Arg.Any <string>()).Returns(new[]
            {
                new Library.Models.Shift {
                    StartDateTime = now.AddDays(1), LocationId = "1", Allocated = true, EmployeeId = "xyz"
                }
            });
            ILocationService locationService = Substitute.For <ILocationService>();

            locationService.GetByName("Contoso").Returns(new Library.Models.Location {
                id = "1", Name = "Contoso"
            });

            ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);

            controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
            ShiftViewModel viewModel = new ShiftViewModel {
                LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till"
            };

            // Act
            await controller.Book(viewModel);

            // Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            shiftRepository.Received(1).Update(Arg.Is <Library.Models.Shift>(x => x.EmployeeId == "123" && x.Allocated == true));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }
        public async Task Book_EmployeeNotOnShift_ShiftRepoHitWithCorrectQuery()
        {
            // Arrange
            IRepository <Library.Models.Shift> shiftRepository = Substitute.For <IRepository <Library.Models.Shift> >();
            DateTime now = DateTime.Now;

            shiftRepository.Get(Arg.Any <string>(), Arg.Any <IDictionary <string, object> >(), Arg.Any <string>()).Returns(new[]
            {
                new Library.Models.Shift {
                    StartDateTime = now, LocationId = "1", Allocated = true, EmployeeId = "abc"
                },
                new Library.Models.Shift {
                    StartDateTime = now.Add(new TimeSpan(1, 0, 0, 0)), LocationId = "1", Allocated = true, EmployeeId = "xyz"
                }
            });
            ILocationService locationService = Substitute.For <ILocationService>();

            locationService.Get()
            .Returns(new[] { new Library.Models.Location {
                                 id = "1", Name = "Contoso"
                             }, new Library.Models.Location {
                                 id = "2", Name = "Fabrikam"
                             } });


            ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService);

            controller.ControllerContext             = new ControllerContext();
            controller.ControllerContext.HttpContext = new DefaultHttpContext();
            controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
            ShiftViewModel viewModel = new ShiftViewModel {
                LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till"
            };

            // Act
            await controller.Book(viewModel);

            // Assert
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            shiftRepository.Received(1).Get(
                "SELECT * FROM c WHERE c.EmployeeId = @employeeId",
                Arg.Any <Dictionary <string, object> >());
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }
        public async Task Book_EmployeeOnShift_ViewDataError()
        {
            // Arrange
            IStringLocalizer <ShiftsController> stringLocalizer = Substitute.For <IStringLocalizer <ShiftsController> >();

            stringLocalizer.GetString("MultipleBookError").Returns(new LocalizedString("MultipleBookError", "You are already booked to work on this day."));


            IRepository <Library.Models.Shift> shiftRepository = Substitute.For <IRepository <Library.Models.Shift> >();
            DateTime now = DateTime.Now;

            shiftRepository.Get(Arg.Any <string>(), Arg.Any <IDictionary <string, object> >(), Arg.Any <string>()).Returns(new[]
            {
                new Library.Models.Shift {
                    StartDateTime = now, LocationId = "1", Allocated = true, EmployeeId = "abc"
                },
                new Library.Models.Shift {
                    StartDateTime = now.Add(new TimeSpan(1, 0, 0, 0)), LocationId = "1", Allocated = true, EmployeeId = "xyz"
                }
            });
            ILocationService locationService = Substitute.For <ILocationService>();

            locationService.Get().Returns(new[] { new Library.Models.Location {
                                                      id = "1", Name = "Contoso"
                                                  }, new Library.Models.Location {
                                                      id = "2", Name = "Fabrikam"
                                                  } });

            ShiftsController controller = this.GetController(shiftRepository: shiftRepository, locationService: locationService, stringLocalizer: stringLocalizer);

            controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity(new[] { new Claim("http://schemas.microsoft.com/identity/claims/objectidentifier", "123") }));
            ShiftViewModel viewModel = new ShiftViewModel {
                LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till"
            };

            // Act
            IActionResult result = await controller.Book(viewModel);

            // Assert
            ViewResult viewResult = Assert.IsType <ViewResult>(result);

            Assert.Equal(stringLocalizer["MultipleBookError"], viewResult.ViewData["ValidationError"]);
        }
        public async Task Book_NoIdClaim_Exception()
        {
            // Arrange
            DateTime         now        = DateTime.Now;
            ShiftsController controller = this.GetController();

            controller.ControllerContext             = new ControllerContext();
            controller.ControllerContext.HttpContext = new DefaultHttpContext();
            controller.HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
            ShiftViewModel viewModel = new ShiftViewModel {
                LocationName = "Contoso", Start = now, End = now.AddHours(9), WorkType = "Till"
            };

            // Assert
            ArgumentException exception = await Assert.ThrowsAsync <ArgumentException>(() => controller.Book(viewModel));

            Assert.Equal("http://schemas.microsoft.com/identity/claims/objectidentifier claim is required", exception.Message);
        }