public void InitializeWithData()
        {
            Employee e1 = new Employee();
            Employee e2 = new Employee();

            Department d1 = new Department();
            Department d2 = new Department();

            using (FakeEmployeeContext ctx = new FakeEmployeeContext(new Employee[] { e1, e2 }, new Department[] { d1, d2 }))
            {
                UnitOfWork unit = new UnitOfWork(ctx);
                ObservableCollection <DepartmentViewModel> departments = new ObservableCollection <DepartmentViewModel>(ctx.Departments.Select(d => new DepartmentViewModel(d)));
                ObservableCollection <EmployeeViewModel>   employees   = new ObservableCollection <EmployeeViewModel>();
                foreach (var e in ctx.Employees)
                {
                    employees.Add(new EmployeeViewModel(e, employees, departments, unit));
                }

                EmployeeWorkspaceViewModel vm = new EmployeeWorkspaceViewModel(employees, departments, unit);

                Assert.IsNotNull(vm.CurrentEmployee, "Current employee should be set if there are departments.");
                Assert.AreSame(employees, vm.AllEmployees, "ViewModel should expose the same instance of the Employee collection so that changes outside the ViewModel are reflected.");
                Assert.AreSame(employees, vm.AllEmployees[0].ManagerLookup, "ViewModel should expose the same instance of the Employee collection to children so that changes outside the ViewModel are reflected.");
                Assert.AreSame(departments, vm.AllEmployees[0].DepartmentLookup, "ViewModel should expose the same instance of the Department collection to children so that changes outside the ViewModel are reflected.");
            }
        }
        public void AddWhenEmployeeNotSelected()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx);

                vm.CurrentEmployee = null;
                TestAddEmployee(ctx, vm);
            }
        }
        public void DeleteCommandOnlyAvailableWhenEmployeeSelected()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx);

                vm.CurrentEmployee = null;
                Assert.IsFalse(vm.DeleteEmployeeCommand.CanExecute(null), "Delete command should be disabled when no employee is selected.");

                vm.CurrentEmployee = vm.AllEmployees.First();
                Assert.IsTrue(vm.DeleteEmployeeCommand.CanExecute(null), "Delete command should be enabled when employee is selected.");
            }
        }
        public void InitializeWithEmptyData()
        {
            using (FakeEmployeeContext ctx = new FakeEmployeeContext())
            {
                UnitOfWork unit = new UnitOfWork(ctx);
                ObservableCollection <DepartmentViewModel> departments = new ObservableCollection <DepartmentViewModel>();
                ObservableCollection <EmployeeViewModel>   employees   = new ObservableCollection <EmployeeViewModel>();
                EmployeeWorkspaceViewModel vm = new EmployeeWorkspaceViewModel(employees, departments, unit);

                Assert.AreSame(employees, vm.AllEmployees, "ViewModel should expose the same instance of the collection so that changes outside the ViewModel are reflected.");
                Assert.IsNull(vm.CurrentEmployee, "Current employee should not be set if there are no department.");
                Assert.IsNotNull(vm.AddEmployeeCommand, "AddEmployeeCommand should be initialized");
                Assert.IsNotNull(vm.DeleteEmployeeCommand, "DeleteEmployeeCommand should be initialized");
            }
        }
        public void ExternalAddToEmployeeCollection()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                UnitOfWork unit = new UnitOfWork(ctx);
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx, unit);

                EmployeeViewModel currentEmployee = vm.CurrentEmployee;
                EmployeeViewModel newEmployee     = new EmployeeViewModel(new Employee(), vm.AllEmployees, new ObservableCollection <DepartmentViewModel>(), unit);

                vm.AllEmployees.Add(newEmployee);
                Assert.IsTrue(vm.AllEmployees.Contains(newEmployee), "New employee should have been added to AllEmployees.");
                Assert.AreSame(currentEmployee, vm.CurrentEmployee, "CurrentEmployee should not have changed.");
                Assert.IsFalse(ctx.IsObjectTracked(newEmployee.Model), "ViewModel is not responsible for adding employees created externally.");
            }
        }
        /// <summary>
        /// 验证向工作区和工作单元添加雇员的操作
        /// </summary>
        /// <param name="unitOfWork">应将雇员添加到的上下文</param>
        /// <param name="vm">要将雇员添加到的工作区</param>
        private static void TestAddEmployee(FakeEmployeeContext ctx, EmployeeWorkspaceViewModel vm)
        {
            List<EmployeeViewModel> originalEmployees = vm.AllEmployees.ToList();

            string lastProperty = null;
            vm.PropertyChanged += (sender, e) => { lastProperty = e.PropertyName; };

            Assert.IsTrue(vm.AddEmployeeCommand.CanExecute(null), "Add command should always be enabled.");
            vm.AddEmployeeCommand.Execute(null);

            Assert.AreEqual(originalEmployees.Count + 1, vm.AllEmployees.Count, "One new employee should have been added to the AllEmployees property.");
            Assert.IsFalse(originalEmployees.Contains(vm.CurrentEmployee), "The new employee should be selected.");
            Assert.IsNotNull(vm.CurrentEmployee, "The new employee should be selected.");
            Assert.AreEqual("CurrentEmployee", lastProperty, "CurrentEmployee should have raised a PropertyChanged.");
            Assert.IsTrue(ctx.IsObjectTracked(vm.CurrentEmployee.Model), "The new employee has not been added to the context.");
        }
        public void ExternalRemoveFromEmployeeCollection()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                UnitOfWork unit = new UnitOfWork(ctx);
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx, unit);

                EmployeeViewModel current  = vm.AllEmployees.First();
                EmployeeViewModel toDelete = vm.AllEmployees.Skip(1).First();
                vm.CurrentEmployee = current;

                vm.AllEmployees.Remove(toDelete);
                Assert.IsFalse(vm.AllEmployees.Contains(toDelete), "Employee should have been removed from AllDepartments.");
                Assert.AreSame(current, vm.CurrentEmployee, "CurrentEmployee should not have changed.");
                Assert.IsTrue(ctx.IsObjectTracked(toDelete.Model), "ViewModel is not responsible for deleting employees removed externally.");
            }
        }
        public void ExternalRemoveSelectedEmployeeFromCollection()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                UnitOfWork unit = new UnitOfWork(ctx);
                EmployeeWorkspaceViewModel vm      = BuildViewModel(ctx, unit);
                EmployeeViewModel          current = vm.CurrentEmployee;

                string lastProperty = null;
                vm.PropertyChanged += (sender, e) => { lastProperty = e.PropertyName; };

                vm.AllEmployees.Remove(current);
                Assert.IsFalse(vm.AllEmployees.Contains(current), "Employee should have been removed from AllEmployees.");
                Assert.IsNull(vm.CurrentEmployee, "CurrentEmployee should have been nulled as it was removed from the collection.");
                Assert.AreEqual("CurrentEmployee", lastProperty, "CurrentEmployee should have raised a PropertyChanged.");
                Assert.IsTrue(ctx.IsObjectTracked(current.Model), "ViewModel is not responsible for deleting employees removed externally.");
            }
        }
        public void CurrentEmployee()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx);

                string lastProperty;
                vm.PropertyChanged += (sender, e) => { lastProperty = e.PropertyName; };

                lastProperty       = null;
                vm.CurrentEmployee = null;
                Assert.IsNull(vm.CurrentEmployee, "CurrentEmployee should have been nulled.");
                Assert.AreEqual("CurrentEmployee", lastProperty, "CurrentEmployee should have raised a PropertyChanged when set to null.");

                lastProperty = null;
                var employee = vm.AllEmployees.First();
                vm.CurrentEmployee = employee;
                Assert.AreSame(employee, vm.CurrentEmployee, "CurrentEmployee has not been set to specified value.");
                Assert.AreEqual("CurrentEmployee", lastProperty, "CurrentEmployee should have raised a PropertyChanged when set to a value.");
            }
        }
        public void DeleteEmployee()
        {
            using (FakeEmployeeContext ctx = BuildContextWithData())
            {
                EmployeeWorkspaceViewModel vm = BuildViewModel(ctx);

                EmployeeViewModel toDelete = vm.CurrentEmployee;
                int originalCount          = vm.AllEmployees.Count;

                string lastProperty = null;
                vm.PropertyChanged += (sender, e) => { lastProperty = e.PropertyName; };

                vm.DeleteEmployeeCommand.Execute(null);

                Assert.AreEqual(originalCount - 1, vm.AllEmployees.Count, "One employee should have been removed from the AllEmployees property.");
                Assert.IsFalse(vm.AllEmployees.Contains(toDelete), "The selected employee should have been removed.");
                Assert.IsFalse(ctx.IsObjectTracked(toDelete.Model), "The selected employee has not been removed from the context.");
                Assert.IsNull(vm.CurrentEmployee, "No employee should be selected after deletion.");
                Assert.AreEqual("CurrentEmployee", lastProperty, "CurrentEmployee should have raised a PropertyChanged.");
            }
        }