diff --git a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs index da4deecd11..4123521ad7 100644 --- a/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs +++ b/src/Tgstation.Server.Host/Components/Chat/Providers/Provider.cs @@ -96,6 +96,9 @@ namespace Tgstation.Server.Host.Components.Chat.Providers Logger = logger ?? throw new ArgumentNullException(nameof(logger)); ChatBot = chatBot ?? throw new ArgumentNullException(nameof(chatBot)); + if (chatBot.Instance == null) + throw new ArgumentException("chatBot must have Instance!", nameof(chatBot)); + messageQueue = new Queue(); nextMessage = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); initialConnectionTcs = new TaskCompletionSource(); @@ -286,7 +289,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers connectNow = false; if (!Connected) { - var job = Job.Create(Api.Models.JobCode.ReconnectChatBot, null, ChatBot.Instance, ChatBotRights.WriteEnabled); + var job = Job.Create(Api.Models.JobCode.ReconnectChatBot, null, ChatBot.Instance!, ChatBotRights.WriteEnabled); job.Description += $": {ChatBot.Name}"; await jobManager.RegisterOperation( diff --git a/src/Tgstation.Server.Host/Jobs/JobService.cs b/src/Tgstation.Server.Host/Jobs/JobService.cs index 0e8714e307..ea2782a821 100644 --- a/src/Tgstation.Server.Host/Jobs/JobService.cs +++ b/src/Tgstation.Server.Host/Jobs/JobService.cs @@ -123,6 +123,9 @@ namespace Tgstation.Server.Host.Jobs if (job.StartedBy != null && job.StartedBy.Name == null) throw new InvalidOperationException("StartedBy User associated with job does not have a Name!"); + if (job.Instance == null) + throw new InvalidOperationException("No Instance associated with job!"); + job.StartedAt = DateTimeOffset.UtcNow; job.Cancelled = false; @@ -458,7 +461,7 @@ namespace Tgstation.Server.Host.Jobs logger.LogTrace("Starting job..."); await operation( - instanceCoreProvider.GetInstance(job.Instance), + instanceCoreProvider.GetInstance(job.Instance!), databaseContextFactory, job, new JobProgressReporter( diff --git a/src/Tgstation.Server.Host/Models/Job.cs b/src/Tgstation.Server.Host/Models/Job.cs index c9af1ffa50..85327de2e2 100644 --- a/src/Tgstation.Server.Host/Models/Job.cs +++ b/src/Tgstation.Server.Host/Models/Job.cs @@ -7,8 +7,6 @@ using Tgstation.Server.Api.Models; using Tgstation.Server.Api.Models.Response; using Tgstation.Server.Api.Rights; -#nullable disable - namespace Tgstation.Server.Host.Models { /// @@ -20,18 +18,18 @@ namespace Tgstation.Server.Host.Models /// See . /// [Required] - public User StartedBy { get; set; } + public User? StartedBy { get; set; } /// /// See . /// - public User CancelledBy { get; set; } + public User? CancelledBy { get; set; } /// /// The the job belongs to if any. /// [Required] - public Instance Instance { get; set; } + public Instance? Instance { get; set; } /// /// Creates a new job for registering in the . @@ -42,7 +40,7 @@ namespace Tgstation.Server.Host.Models /// The used to generate the value of . /// The value of . will be derived from this. /// A new ready to be registered with the . - public static Job Create(JobCode code, User startedBy, Api.Models.Instance instance, TRight cancelRight) + public static Job Create(JobCode code, User? startedBy, Api.Models.Instance instance, TRight cancelRight) where TRight : Enum => new( code, @@ -58,7 +56,7 @@ namespace Tgstation.Server.Host.Models /// The value of . If , the user will be used. /// The used to generate the value of . /// A new ready to be registered with the . - public static Job Create(JobCode code, User startedBy, Api.Models.Instance instance) + public static Job Create(JobCode code, User? startedBy, Api.Models.Instance instance) => new( code, startedBy, @@ -91,7 +89,7 @@ namespace Tgstation.Server.Host.Models /// The value of . /// The value of . /// The value of . - Job(JobCode code, User startedBy, Api.Models.Instance instance, RightsType? cancelRightsType, ulong? cancelRight) + Job(JobCode code, User? startedBy, Api.Models.Instance instance, RightsType? cancelRightsType, ulong? cancelRight) { StartedBy = startedBy; ArgumentNullException.ThrowIfNull(instance); @@ -100,7 +98,7 @@ namespace Tgstation.Server.Host.Models Id = instance.Id ?? throw new InvalidOperationException("Instance associated with job does not have an Id!"), }; Description = typeof(JobCode) - .GetField(code.ToString()) + .GetField(code.ToString())! .GetCustomAttributes(false) .OfType() .First() @@ -114,8 +112,8 @@ namespace Tgstation.Server.Host.Models public JobResponse ToApi() => new() { Id = Id, - JobCode = JobCode.Value, - InstanceId = Instance.Id.Value, + JobCode = this.Require(x => x.JobCode), + InstanceId = (Instance ?? throw new InvalidOperationException("Instance needs to be set!")).Require(x => x.Id), StartedAt = StartedAt, StoppedAt = StoppedAt, Cancelled = Cancelled, @@ -125,7 +123,7 @@ namespace Tgstation.Server.Host.Models Description = Description, ExceptionDetails = ExceptionDetails, ErrorCode = ErrorCode, - StartedBy = StartedBy.CreateUserName(), + StartedBy = (StartedBy ?? throw new InvalidOperationException("StartedBy needs to be set!")).CreateUserName(), }; } } diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs index 61d61a19a3..58c63c6a99 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestDiscordProvider.cs @@ -1,11 +1,11 @@ using System; -using System.Collections.Generic; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; using Tgstation.Server.Api.Models; @@ -31,7 +31,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests testToken1 = new ChatBot { ConnectionString = actualToken, - ReconnectionInterval = 1 + ReconnectionInterval = 1, + Instance = new Models.Instance() }; var mockSetup = new Mock(); @@ -52,6 +53,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests { ConnectionString = "fake_token", ReconnectionInterval = 1, + Instance = new Models.Instance(), }; Assert.ThrowsException(() => new DiscordProvider(null, null, null, null, null, null)); @@ -76,7 +78,8 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests await using var provider = new DiscordProvider(mockJobManager, Mock.Of(), mockLogger.Object, Mock.Of(), new ChatBot { ReconnectionInterval = 1, - ConnectionString = "asdf" + ConnectionString = "asdf", + Instance = new Models.Instance(), }, new GeneralConfiguration()); await Assert.ThrowsExceptionAsync(async () => await InvokeConnect(provider)); Assert.IsFalse(provider.Connected); diff --git a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs index 60021ea019..3f1e050219 100644 --- a/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs +++ b/tests/Tgstation.Server.Host.Tests/Components/Chat/Providers/TestIrcProvider.cs @@ -1,14 +1,12 @@ using System; -using System.Collections.Generic; using System.Reflection; using System.Threading; using System.Threading.Tasks; -using System.Xml.Linq; using Microsoft.Extensions.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; -using Serilog.Parsing; using Tgstation.Server.Api.Models; using Tgstation.Server.Host.Jobs; @@ -37,6 +35,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests var mockBot = new ChatBot { Name = "test", + Instance = new Models.Instance(), Provider = ChatProvider.Irc }; @@ -83,6 +82,7 @@ namespace Tgstation.Server.Host.Components.Chat.Providers.Tests { ConnectionString = actualToken, Provider = ChatProvider.Irc, + Instance = new Models.Instance(), }); Assert.IsFalse(provider.Connected); await InvokeConnect(provider);