public void TestChange_Job_AddNew()
        {
            DoWithData((session, provider) =>
            {
                // берем дату проверки
                var checkDate = DateTime.Now;

                // засыпаем на 2 секунды, чтобы детектить изменения
                Thread.Sleep(TimeSpan.FromSeconds(2));

                // у Job1 добавляем новый параметр
                var job1   = session.Query <SchJob>().Single(i => i.Code == "TST_JOB1");
                var newJob = new SchJob
                {
                    Code      = "TST_NEWJOB",
                    JobType   = job1.JobType,
                    Scheduler = job1.Scheduler
                };
                session.Save(newJob);
                var jobNewTrigger1 = new SchCronTrigger
                {
                    Code           = "TST_JOBNEW_TR1",
                    Scheduler      = job1.Scheduler,
                    StartTimeUtc   = DateTime.UtcNow.AddDays(-1),
                    Job            = newJob,
                    CronExpression = SampleCronExpression
                };
                session.Save(jobNewTrigger1);
                newJob.Job_SchTrigger_List.Add(jobNewTrigger1);

                session.Flush();

                // поехали
                JobKey[] deletedJobs;
                IDictionary <IJobDetail, Quartz.Collection.ISet <ITrigger> > changedJobs;

                provider.GetChangedJobs(TstSchedulerName, checkDate, out deletedJobs, out changedJobs);

                // проверяем
                deletedJobs.Should().HaveCount(0);
                changedJobs.Should().HaveCount(1);
                changedJobs.Keys.Single().Key.Name.ShouldBeEquivalentTo(newJob.Code);
                changedJobs.Values.Single().Should().HaveCount(1);
                changedJobs.Values.Single().Single().Key.Name.ShouldBeEquivalentTo(jobNewTrigger1.Code);
            });
        }
        public void TestChange_Trigger_AddOneMore()
        {
            DoWithData((session, provider) =>
            {
                // берем дату проверки
                var checkDate = DateTime.Now;

                // засыпаем на 2 секунды, чтобы детектить изменения
                Thread.Sleep(TimeSpan.FromSeconds(2));

                // у job 1 добавляем 2ой триггер
                var job1         = session.Query <SchJob>().Single(i => i.Code == "TST_JOB1");
                var job1Trigger2 = new SchCronTrigger
                {
                    Scheduler      = job1.Scheduler,
                    Code           = "TST_JOB1_TR2",
                    Job            = job1,
                    StartTimeUtc   = DateTime.UtcNow.AddDays(-1),
                    CronExpression = SampleCronExpression
                };
                session.Save(job1Trigger2);
                job1.Job_SchTrigger_List.Add(job1Trigger2);

                session.Flush();

                // поехали
                JobKey[] deletedJobs;
                IDictionary <IJobDetail, Quartz.Collection.ISet <ITrigger> > changedJobs;
                provider.GetChangedJobs(TstSchedulerName, checkDate, out deletedJobs, out changedJobs);

                // проверяем
                deletedJobs.Should().HaveCount(0);
                changedJobs.Should().HaveCount(1);
                changedJobs.Keys.Single().Key.Name.ShouldBeEquivalentTo("TST_JOB1");
                changedJobs.Values.Should().HaveCount(1);
                changedJobs.Values.Single().Should().HaveCount(2);
                changedJobs.Values.Single().Should().ContainSingle(i => i.Key.Name == "TST_JOB1_TR1");
                changedJobs.Values.Single().Should().ContainSingle(i => i.Key.Name == "TST_JOB1_TR2");
            });
        }
        /// <summary>
        /// Сценарий:
        /// Job1 - нормальный
        /// Job2 - имеет один триггер с датой старта больше текущей
        /// Job3 - имеет один триггер с датой окончания меньше текущей
        /// Job4 - имеет один заблокированный триггер
        /// Job5 - имеет два триггера: один заблокирован, один нормальный
        /// </summary>
        /// <param name="session"></param>
        private static void PopulateTestData(ISession session)
        {
            var scheduler = new SchScheduler {
                Code = TstSchedulerName
            };

            session.Save(scheduler);

            var jobType = new SchJobType
            {
                Code      = "TST Job Type",
                ClassName = string.Format("{0}, MLC.Wms.Scheduler.Tests", typeof(FakeJob).FullName),
                Scheduler = scheduler
            };

            session.Save(jobType);

            var job1 = new SchJob
            {
                JobType   = jobType,
                Code      = "TST_JOB1",
                Scheduler = scheduler
            };

            session.Save(job1);

            var job1Param1 = new SchJobParam
            {
                Name  = "TST_JOB1_PARAM1",
                Job   = job1,
                Value = "TST VALUE"
            };

            session.Save(job1Param1);
            job1.Job_SchJobParam_List.Add(job1Param1);

            var job1Trigger1 = new SchCronTrigger
            {
                Code               = "TST_JOB1_TR1",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(-1),
                Job       = job1,
                Scheduler = scheduler
            };

            session.Save(job1Trigger1);
            job1.Job_SchTrigger_List.Add(job1Trigger1);

            // job 2
            var job2 = new SchJob
            {
                JobType   = jobType,
                Code      = "TST_JOB2",
                Scheduler = scheduler
            };

            session.Save(job2);
            var job2Trigger1 = new SchCronTrigger
            {
                Code               = "TST_JOB2_TR1",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(1),
                Job       = job2,
                Scheduler = scheduler
            };

            session.Save(job2Trigger1);
            job2.Job_SchTrigger_List.Add(job2Trigger1);

            // job 3
            var job3 = new SchJob
            {
                JobType   = jobType,
                Code      = "TST_JOB3",
                Scheduler = scheduler
            };

            session.Save(job3);
            var job3Trigger1 = new SchCronTrigger
            {
                Code               = "TST_JOB3_TR1",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(-2),
                EndTimeUtc         = DateTime.UtcNow.AddDays(-1),
                Job       = job3,
                Scheduler = scheduler
            };

            session.Save(job3Trigger1);
            job3.Job_SchTrigger_List.Add(job3Trigger1);

            // job 4
            var job4 = new SchJob
            {
                JobType   = jobType,
                Code      = "TST_JOB4",
                Scheduler = scheduler
            };

            session.Save(job4);
            var job4Trigger1 = new SchCronTrigger
            {
                Code               = "TST_JOB4_TR1",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(-2),
                EndTimeUtc         = DateTime.UtcNow.AddDays(+1),
                Disabled           = true,
                Job       = job4,
                Scheduler = scheduler
            };

            session.Save(job4Trigger1);
            job4.Job_SchTrigger_List.Add(job4Trigger1);

            // job 5
            var job5 = new SchJob
            {
                JobType   = jobType,
                Code      = "TST_JOB5",
                Scheduler = scheduler
            };

            session.Save(job5);
            var job5Trigger1 = new SchCronTrigger
            {
                Code               = "TST_JOB5_TR1",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(-2),
                EndTimeUtc         = DateTime.UtcNow.AddDays(+1),
                Disabled           = true,
                Job       = job5,
                Scheduler = scheduler
            };

            session.Save(job5Trigger1);
            job5.Job_SchTrigger_List.Add(job5Trigger1);

            var job5Trigger2 = new SchCronTrigger
            {
                Code               = "TST_JOB5_TR2",
                CronExpression     = SampleCronExpression,
                MisfireInstruction = 1,
                StartTimeUtc       = DateTime.UtcNow.AddDays(-2),
                EndTimeUtc         = DateTime.UtcNow.AddDays(+1),
                Job       = job5,
                Scheduler = scheduler
            };

            session.Save(job5Trigger2);
            job5.Job_SchTrigger_List.Add(job5Trigger2);
        }