public void ScheduledJobs_ReturnsCorrectResult()
    {
        var now  = DateTime.UtcNow;
        var data = new Dictionary <string, string>
        {
            ["EnqueueAt"]   = JobHelper.SerializeDateTime(now),
            ["ScheduledAt"] = JobHelper.SerializeDateTime(now.AddSeconds(1)),
        };
        var invocationData = CreateInvocationData(() => SampleMethod("Arguments"));
        var jobs           = Enumerable.Range(0, 5).
                             Select(x =>
        {
            var job = new HangfireJob
            {
                CreatedAt      = now + new TimeSpan(0, 0, x),
                InvocationData = invocationData,
            };
            var state = new HangfireState
            {
                CreatedAt = DateTime.UtcNow,
                Name      = ScheduledState.StateName,
                Data      = SerializationHelper.Serialize(data),
            };
            job.States.Add(state);
            return(job);
        }).
                             ToArray();

        UseContextSavingChanges(context =>
        {
            foreach (var job in jobs)
            {
                context.Add(job);
            }
            context.SaveChanges();
            foreach (var job in jobs)
            {
                var state     = job.States.Single();
                job.State     = state;
                job.StateName = state.Name;
            }
        });

        var result = UseMonitoringApi(instance => instance.ScheduledJobs(1, 2));

        Assert.NotNull(result);
        Assert.Equal(2, result.Count);

        Assert.All(result, item =>
        {
            Assert.NotNull(item.Key);
            var value = item.Value;
            Assert.NotNull(value);
            Assert.Equal(now, value.EnqueueAt);
            Assert.Equal(now.AddSeconds(1), value.ScheduledAt);
        });

        Assert.Equal(jobs[2].Id.ToString(CultureInfo.InvariantCulture), result[1].Key);
        Assert.Equal(jobs[3].Id.ToString(CultureInfo.InvariantCulture), result[0].Key);
    }
    private static void AddJobWithStateToContext(
        HangfireContext context,
        string stateName,
        IDictionary <string, string> data = null)
    {
        data ??= new Dictionary <string, string>();
        var state = new HangfireState
        {
            CreatedAt = DateTime.UtcNow,
            Name      = stateName,
            Data      = SerializationHelper.Serialize(data),
        };
        var job = new HangfireJob
        {
            CreatedAt      = DateTime.UtcNow,
            InvocationData = CreateInvocationData(() => SampleMethod(null)),
            States         = new[]
            {
                state,
            },
        };

        context.Add(job);
        context.SaveChanges();
        job.State     = state;
        job.StateName = state.Name;
        context.SaveChanges();
    }
    public void JobDetails_ReturnsCorrectResult()
    {
        var createdAt      = DateTime.UtcNow;
        var stateCreatedAt = createdAt.AddSeconds(1);
        var data           = new Dictionary <string, string>
        {
            ["Name"] = "Value",
        };
        var parameters = new Dictionary <string, string>
        {
            ["Key1"] = "Value1",
            ["Key2"] = "Value2",
        };
        var state = new HangfireState
        {
            Name      = "State",
            Reason    = "Reason",
            CreatedAt = stateCreatedAt,
            Data      = SerializationHelper.Serialize(data),
        };
        var job = new HangfireJob
        {
            CreatedAt      = createdAt,
            InvocationData = CreateInvocationData(() => SampleMethod("argument")),
            ExpireAt       = createdAt + new TimeSpan(1, 0, 0, 0),
            States         = new[]
            {
                state,
            },
            Parameters = parameters.
                         Select(x => new HangfireJobParameter
            {
                Name  = x.Key,
                Value = x.Value,
            }).
                         ToList(),
        };

        UseContextSavingChanges(context => context.Add(job));
        var jobId = job.Id.ToString(CultureInfo.InvariantCulture);

        var result = UseMonitoringApi(instance => instance.JobDetails(jobId));

        Assert.NotNull(result);
        Assert.Equal(createdAt, result.CreatedAt);
        Assert.Equal(createdAt.AddDays(1), result.ExpireAt);
        Assert.Equal(typeof(EFCoreStorageTest), result.Job.Type);
        Assert.Equal(nameof(SampleMethod), result.Job.Method.Name);
        Assert.Equal(new[] { "argument" }, result.Job.Args);
        Assert.NotNull(result.History);
        var historyItem = result.History.Single();

        Assert.Equal("State", historyItem.StateName);
        Assert.Equal("Reason", historyItem.Reason);
        Assert.Equal(stateCreatedAt, historyItem.CreatedAt);
        Assert.Equal(data, historyItem.Data);
        Assert.NotNull(result.Properties);
        Assert.Equal(parameters, result.Properties);
    }
    public void FetchedJobs_ReturnsCorrectResult()
    {
        var now            = DateTime.UtcNow;
        var queue          = "queue";;
        var invocationData = CreateInvocationData(() => SampleMethod("Argument"));
        var jobs           = Enumerable.Range(0, 3).
                             Select(x =>
        {
            var createdAt = now - new TimeSpan(0, 0, x);
            var data      = new Dictionary <string, string>
            {
                ["EnqueuedAt"] = JobHelper.SerializeDateTime(createdAt),
            };
            var state = new HangfireState
            {
                CreatedAt = createdAt,
                Name      = EnqueuedState.StateName,
                Reason    = "Reason",
                Data      = SerializationHelper.Serialize(data),
            };
            var job = new HangfireJob
            {
                CreatedAt      = createdAt,
                InvocationData = invocationData,
                States         = new[]
                {
                    state,
                },
                QueuedJobs = new[]
                {
                    new HangfireQueuedJob
                    {
                        Queue     = queue,
                        FetchedAt = now,
                    },
                }
            };
            return(job);
        }).
                             ToArray();

        UseContextSavingChanges(context =>
        {
            foreach (var job in jobs)
            {
                context.Add(job);
            }
            context.SaveChanges();
            foreach (var job in jobs)
            {
                var state     = job.States.Single();
                job.State     = state;
                job.StateName = state.Name;
            }
        });

        var result = UseMonitoringApi(instance => instance.FetchedJobs(queue, 1, 2));

        Assert.NotNull(result);
        Assert.Equal(2, result.Count);

        Assert.All(result, item =>
        {
            Assert.NotNull(item.Key);
            var id    = long.Parse(item.Key, CultureInfo.InvariantCulture);
            var job   = Assert.Single(jobs.Where(x => x.Id == id));
            var value = item.Value;
            Assert.NotNull(value);
            Assert.Equal(now, value.FetchedAt);
            Assert.Equal(job.StateName, value.State);
            Assert.Equal(job.State.Name, value.State);
        });
    }