Skip to content

Commit

Permalink
Add a JobDetail entity and configuration.
Browse files Browse the repository at this point in the history
  • Loading branch information
SeanFarrow committed Dec 10, 2023
1 parent 84ca25b commit dceb917
Show file tree
Hide file tree
Showing 5 changed files with 304 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;

namespace QuartzNet.EntityFrameworkCore.Entities.Configuration;

public class JobDetailEntityConfiguration : IEntityTypeConfiguration<JobDetail>
{
public void Configure(EntityTypeBuilder<JobDetail> builder)
{
builder.ToTable("JobDetails", "Quartz");
builder.HasKey("SchedulerName", "JobName", "JobGroup");
builder.Property(x => x.SchedulerName).IsRequired().HasMaxLength(120);
builder.Property(x => x.JobName).IsRequired().HasMaxLength(150);
builder.Property(x => x.JobGroup).IsRequired().HasMaxLength(150);
builder.Property(x =>x.Description).HasMaxLength(250);
builder.Property(x => x.JobClassName).IsRequired().HasMaxLength(250);
builder.Property(x => x.IsDurable).IsRequired();
builder.Property(x => x.IsNonConcurrent).IsRequired();
builder.Property(x => x.IsUpdateData).IsRequired();
builder.Property(x => x.RequestsRecovery).IsRequired();
builder.Property(x => x.JobData);
}
}
69 changes: 69 additions & 0 deletions src/QuartzNet.EntityFrameworkCore/Entities/JobDetail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
namespace QuartzNet.EntityFrameworkCore.Entities;

public class JobDetail
{
public JobDetail(string schedulerName, string jobName, string jobGroup, string? description, string jobClassName, bool isDurable, bool isNonConcurrent, bool isUpdateData, bool requestsRecovery, string? jobData)
{
if (schedulerName is null)
{
throw new ArgumentNullException(nameof(schedulerName));
}

if (schedulerName.Length is 0)
{
throw new ArgumentException(nameof(schedulerName));
}
SchedulerName = schedulerName;

if (jobName is null)
{
throw new ArgumentNullException(nameof(jobName));
}

if (jobName.Length is 0)
{
throw new ArgumentException(nameof(jobName));
}
JobName = jobName;

if (jobGroup is null)
{
throw new ArgumentNullException(nameof(jobGroup));
}

if (jobGroup.Length is 0)
{
throw new ArgumentException(nameof(jobGroup));
}
JobGroup = jobGroup;

if (jobClassName is null)
{
throw new ArgumentNullException(nameof(jobClassName));
}

if (jobClassName.Length is 0)
{
throw new ArgumentException(nameof(jobClassName));
}
JobClassName= jobClassName;

IsDurable = isDurable;
IsNonConcurrent = isNonConcurrent;
IsUpdateData = isUpdateData;
RequestsRecovery = requestsRecovery;
Description = description;
JobData = jobData;
}

public string SchedulerName { get; }
public string JobName { get; }
public string JobGroup { get; }
public string? Description { get; }
public string JobClassName { get; }
public bool IsDurable { get; }
public bool IsNonConcurrent { get; }
public bool IsUpdateData { get; }
public bool RequestsRecovery { get; }
public string? JobData { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using QuartzNet.EntityFrameworkCore.Entities;
using QuartzNet.EntityFrameworkCore.Entities.Configuration;
using FluentAssertions;
using FluentAssertions.Execution;
using Microsoft.EntityFrameworkCore;

namespace QuartzNet.EntityFrameworkCore.Tests.Unit.Entities.Configuration;

public class JobDetailEntityConfigurationTests : EntityTypeConfigurationTestsBase<JobDetailEntityConfiguration, JobDetail>
{
[Fact]
public void Configure_ConfiguresTheJobDetailEntityAsExpected()
{
var sut = CreateSut();
var entityBuilder = GetEntityBuilder();

sut.Configure(entityBuilder);
var metadata = entityBuilder.Metadata;

using var scope = new AssertionScope();
metadata.GetSchema().Should().Be("Quartz");
metadata.GetTableName().Should().Be("JobDetails");
var schedulerNameProperty = metadata.FindDeclaredProperty("SchedulerName");
ValidateModelProperty(schedulerNameProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetMaxLength().Should().Be(120);
x?.GetContainingKeys().Should().HaveCount(1);
});

var jobNameProperty = metadata.FindDeclaredProperty("JobName");
ValidateModelProperty(jobNameProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetMaxLength().Should().Be(150);
x?.GetContainingKeys().Should().HaveCount(1);
});

var jobGroupProperty = metadata.FindDeclaredProperty("JobGroup");
ValidateModelProperty(jobGroupProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetMaxLength().Should().Be(150);
x?.GetContainingKeys().Should().HaveCount(1);
});

var descriptionProperty = metadata.FindDeclaredProperty("Description");
ValidateModelProperty(descriptionProperty, x =>
{
x?.IsNullable.Should().BeTrue();
x?.GetMaxLength().Should().Be(250);
x?.GetContainingKeys().Should().BeEmpty();
});

var jobClassNameProperty = metadata.FindDeclaredProperty("JobClassName");
ValidateModelProperty(jobClassNameProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetMaxLength().Should().Be(250);
x?.GetContainingKeys().Should().BeEmpty();
});

var isDurableProperty = metadata.FindDeclaredProperty("IsDurable");
ValidateModelProperty(isDurableProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetContainingKeys().Should().BeEmpty();
});

var isNonConcurrentProperty = metadata.FindDeclaredProperty("IsNonConcurrent");
ValidateModelProperty(isNonConcurrentProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetContainingKeys().Should().BeEmpty();
});

var isUpdateDataProperty = metadata.FindDeclaredProperty("IsUpdateData");
ValidateModelProperty(isUpdateDataProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetContainingKeys().Should().BeEmpty();
});

var requestsRecoveryProperty = metadata.FindDeclaredProperty("RequestsRecovery");
ValidateModelProperty(requestsRecoveryProperty, x =>
{
x?.IsNullable.Should().BeFalse();
x?.GetContainingKeys().Should().BeEmpty();
});

var jobDataProperty = metadata.FindDeclaredProperty("JobData");
ValidateModelProperty(jobDataProperty, x =>
{
x?.IsNullable.Should().BeTrue();
x?.GetContainingKeys().Should().BeEmpty();
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
using FluentAssertions;
using QuartzNet.EntityFrameworkCore.Entities;

namespace QuartzNet.EntityFrameworkCore.Tests.Unit.Entities;

public class JobDetailTests
{
#region Private members.
private string _schedulerName ="test scheduler";
private string _jobName ="test job";
private string _jobGroup ="test job group";
private readonly string? _description ="Test job description";
private string _jobClassName = "QuartzNet.EntityFrameworkCore.Tests.Unit.Fakes.FakeJob";
private readonly bool _isDurable =false;
private readonly bool _isNonConcurrent =false;
private readonly bool _isUpdateData =false;
private readonly bool _requestsRecovery =false;
private string? _jobData="TestJobData";

private JobDetail CreateSut() =>new(_schedulerName, _jobName, _jobGroup, _description, _jobClassName, _isDurable, _isNonConcurrent, _isUpdateData, _requestsRecovery, _jobData);
#endregion

#region Constructor tests.
[Fact]
public void AnArgumentNullExceptionShouldBeThrownWhenTheSchedulerNamePassedInIsNull()
{
_schedulerName = null!;

var act = CreateSut;

act.Should().Throw<ArgumentNullException>();
}

[Fact]
public void AnArgumentExceptionShouldBeThrownWhenTheSchedulerNamePassedInIsAnEmptyString()
{
_schedulerName = String.Empty;

var act = CreateSut;

act.Should().Throw<ArgumentException>();
}

[Fact]
public void AnArgumentNullExceptionShouldBeThrownWhenTheJobNamePassedInIsNull()
{
_jobName = null!;

var act = CreateSut;

act.Should().Throw<ArgumentNullException>();
}

[Fact]
public void AnArgumentExceptionShouldBeThrownWhenTheJobNamePassedInIsAnEmptyString()
{
_jobName = String.Empty;

var act = CreateSut;

act.Should().Throw<ArgumentException>();
}

[Fact]
public void AnArgumentNullExceptionShouldBeThrownWhenTheJobGroupPassedInIsNull()
{
_jobGroup = null!;

var act = CreateSut;

act.Should().Throw<ArgumentNullException>();
}

[Fact]
public void AnArgumentExceptionShouldBeThrownWhenTheJobGroupPassedInIsAnEmptyString()
{
_jobGroup = String.Empty;

var act = CreateSut;

act.Should().Throw<ArgumentException>();
}

[Fact]
public void AnArgumentNullExceptionShouldBeThrownWhenTheJobClassNamePassedInIsNull()
{
_jobClassName = null!;

var act = CreateSut;

act.Should().Throw<ArgumentNullException>();
}

[Fact]
public void AnArgumentExceptionShouldBeThrownWhenTheJobClassNamePassedInIsAnEmptyString()
{
_jobClassName = String.Empty;

var act = CreateSut;

act.Should().Throw<ArgumentException>();
}

[Fact]
public void AJobDetailInstanceShouldBeInstantiatedWhenAllParametersAreValid()
{
var result = CreateSut();

result.Should().NotBeNull();
}
#endregion
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
Expand All @@ -11,6 +11,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
Expand Down

0 comments on commit dceb917

Please sign in to comment.