Write tests, fix bugs

This commit is contained in:
Jordan Brown
2020-04-20 15:11:28 -04:00
parent cc2cdeb941
commit 22ff4e6737
8 changed files with 90 additions and 30 deletions
@@ -5,7 +5,7 @@ using Tgstation.Server.Api.Models;
namespace Tgstation.Server.Client
{
/// <summary>
/// Occurs when the server returns an unknown response
/// Occurs when the server returns a bad request response if the <see cref="ApiException.ErrorCode"/> is present. The server returned an unknown reponse otherwise.
/// </summary>
public sealed class ApiConflictException : ApiException
{
@@ -24,6 +24,7 @@ namespace Tgstation.Server.Host.Controllers
/// <see cref="ApiController"/> for managing <see cref="Api.Models.ChatBot"/>s
/// </summary>
[Route(Routes.Chat)]
#pragma warning disable CA1506 // TODO: Decomplexify
public sealed class ChatController : ApiController
{
/// <summary>
@@ -84,7 +85,7 @@ namespace Tgstation.Server.Host.Controllers
.ConfigureAwait(false);
if (countOfExistingBotsInInstance >= Instance.ChatBotLimit.Value)
return BadRequest(new ErrorMessage(ErrorCode.ChatBotMax));
return Conflict(new ErrorMessage(ErrorCode.ChatBotMax));
model.Enabled = model.Enabled ?? false;
model.ReconnectionInterval = model.ReconnectionInterval ?? 1;
@@ -98,7 +99,8 @@ namespace Tgstation.Server.Host.Controllers
Channels = model.Channels?.Select(x => ConvertApiChatChannel(x)).ToList() ?? new List<Models.ChatChannel>(), // important that this isn't null
InstanceId = Instance.Id,
Provider = model.Provider,
ReconnectionInterval = model.ReconnectionInterval
ReconnectionInterval = model.ReconnectionInterval,
ChannelLimit = model.ChannelLimit
};
DatabaseContext.ChatBots.Add(dbModel);
@@ -206,8 +208,8 @@ namespace Tgstation.Server.Host.Controllers
[TgsAuthorize(ChatBotRights.WriteChannels | ChatBotRights.WriteConnectionString | ChatBotRights.WriteEnabled | ChatBotRights.WriteName | ChatBotRights.WriteProvider)]
[ProducesResponseType(200)]
[ProducesResponseType(typeof(Api.Models.ChatBot), 200)]
#pragma warning disable CA1502 // TODO: Decomplexify
#pragma warning disable CA1506
#pragma warning disable CA1502 // TODO: Decomplexify
#pragma warning disable CA1506
public async Task<IActionResult> Update([FromBody] Api.Models.ChatBot model, CancellationToken cancellationToken)
#pragma warning restore CA1502
#pragma warning restore CA1506
@@ -227,7 +229,13 @@ namespace Tgstation.Server.Host.Controllers
return StatusCode((int)HttpStatusCode.Gone);
if ((model.Channels?.Count ?? current.Channels.Count) > (model.ChannelLimit ?? current.ChannelLimit.Value))
return BadRequest(new ErrorMessage(ErrorCode.ChatBotMaxChannels));
{
// 400 or 409 depends on if the client sent both
var errorMessage = new ErrorMessage(ErrorCode.ChatBotMaxChannels);
if (model.Channels != null && model.ChannelLimit.HasValue)
return BadRequest(errorMessage);
return Conflict(errorMessage);
}
var userRights = (ChatBotRights)AuthenticationContext.GetRight(RightsType.ChatBots);
@@ -326,4 +334,5 @@ namespace Tgstation.Server.Host.Controllers
return null;
}
}
#pragma warning restore CA1506
}
@@ -439,7 +439,7 @@ namespace Tgstation.Server.Host.Controllers
.ConfigureAwait(false);
if (countOfExistingChatBots > model.ChatBotLimit.Value)
return BadRequest(new ErrorMessage(ErrorCode.ChatBotMax));
return Conflict(new ErrorMessage(ErrorCode.ChatBotMax));
}
// ensure the current user has write privilege on the instance
+3 -1
View File
@@ -39,7 +39,9 @@ namespace Tgstation.Server.Host.Models
Enabled = Enabled,
Provider = Provider,
Id = Id,
Name = Name
Name = Name,
ChannelLimit = ChannelLimit,
ReconnectionInterval = ReconnectionInterval
};
}
}
+2 -1
View File
@@ -63,7 +63,8 @@ namespace Tgstation.Server.Host.Models
Id = Id,
Name = Name,
Path = Path,
Online = Online
Online = Online,
ChatBotLimit = ChatBotLimit
};
}
}
@@ -1,9 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Client;
using Tgstation.Server.Client.Components;
namespace Tgstation.Server.Tests.Instance
@@ -11,13 +13,17 @@ namespace Tgstation.Server.Tests.Instance
sealed class ChatTest
{
readonly IChatBotsClient chatClient;
readonly IInstanceManagerClient instanceClient;
readonly Api.Models.Instance metadata;
public ChatTest(IChatBotsClient chatBotsClient)
public ChatTest(IChatBotsClient chatClient, IInstanceManagerClient instanceClient, Api.Models.Instance metadata)
{
chatClient = chatBotsClient ?? throw new ArgumentNullException(nameof(chatBotsClient));
this.chatClient = chatClient ?? throw new ArgumentNullException(nameof(chatClient));
this.instanceClient = instanceClient ?? throw new ArgumentNullException(nameof(instanceClient));
this.metadata = metadata ?? throw new ArgumentNullException(nameof(metadata));
}
public async Task Run()
public async Task Run(CancellationToken cancellationToken)
{
var firstBot = new ChatBot
{
@@ -25,22 +31,23 @@ namespace Tgstation.Server.Tests.Instance
Enabled = false,
Name = "r4407",
Provider = ChatProvider.Discord,
ReconnectionInterval = 1
ReconnectionInterval = 1,
ChannelLimit = 1
};
firstBot = await chatClient.Create(firstBot, default);
firstBot = await chatClient.Create(firstBot, cancellationToken);
Assert.AreNotEqual(0, firstBot.Id);
var bots = await chatClient.List(default);
var bots = await chatClient.List(cancellationToken);
Assert.AreEqual(1, bots.Count);
Assert.AreEqual(firstBot.Id, bots.First().Id);
var retrievedBot = await chatClient.GetId(firstBot, default);
Assert.AreEqual(firstBot.Id, retrievedBot);
var retrievedBot = await chatClient.GetId(firstBot, cancellationToken);
Assert.AreEqual(firstBot.Id, retrievedBot.Id);
firstBot.Enabled = true;
var updatedBot = await chatClient.Update(firstBot, default);
var updatedBot = await chatClient.Update(firstBot, cancellationToken);
Assert.AreEqual(true, updatedBot.Enabled);
@@ -56,21 +63,55 @@ namespace Tgstation.Server.Tests.Instance
DiscordChannelId = channelId
}
};
updatedBot = await chatClient.Update(firstBot, default);
updatedBot = await chatClient.Update(firstBot, cancellationToken);
Assert.AreEqual(true, updatedBot.Enabled);
Assert.IsNotNull(updatedBot.Channels);
Assert.AreEqual(1, updatedBot.Channels.Count);
Assert.AreEqual(true, updatedBot.Channels.First().IsAdminChannel);
Assert.AreEqual(true, updatedBot.Channels.First().IsUpdatesChannel);
Assert.AreEqual(false, updatedBot.Channels.First().IsUpdatesChannel);
Assert.AreEqual(true, updatedBot.Channels.First().IsWatchdogChannel);
Assert.AreEqual("butt", updatedBot.Channels.First().Tag);
Assert.AreEqual(channelId, updatedBot.Channels.First().DiscordChannelId);
Assert.IsNull(updatedBot.Channels.First().IrcChannel);
await chatClient.Delete(firstBot, default);
bots = await chatClient.List(default);
await ApiAssert.ThrowsException<ConflictException>(() => chatClient.Create(new ChatBot
{
Name = "asdf",
ConnectionString = "asdf",
Provider = ChatProvider.Irc
}, cancellationToken), ErrorCode.ChatBotMax);
// We limited chat bots and channels to 1, try violating them
updatedBot.Channels.Add(
new ChatChannel
{
IsAdminChannel = true,
IsUpdatesChannel = false,
IsWatchdogChannel = true,
Tag = "butt",
DiscordChannelId = channelId
});
await ApiAssert.ThrowsException<ApiConflictException>(() => chatClient.Update(updatedBot, cancellationToken), ErrorCode.ChatBotMaxChannels);
var oldChannels = updatedBot.Channels;
updatedBot.Channels = null;
updatedBot.ChannelLimit = 0;
await ApiAssert.ThrowsException<ConflictException>(() => chatClient.Update(updatedBot, cancellationToken), ErrorCode.ChatBotMaxChannels);
updatedBot.Channels = oldChannels;
updatedBot.ChannelLimit = null;
await ApiAssert.ThrowsException<ConflictException>(() => chatClient.Update(updatedBot, cancellationToken), ErrorCode.ChatBotMaxChannels);
var instance = metadata.CloneMetadata();
instance.ChatBotLimit = 0;
await ApiAssert.ThrowsException<ConflictException>(() => instanceClient.Update(instance, cancellationToken), ErrorCode.ChatBotMax);
await chatClient.Delete(firstBot, cancellationToken);
bots = await chatClient.List(cancellationToken);
Assert.AreEqual(0, bots.Count);
}
}
@@ -1,6 +1,7 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Tgstation.Server.Client;
using Tgstation.Server.Client.Components;
namespace Tgstation.Server.Tests.Instance
@@ -8,20 +9,25 @@ namespace Tgstation.Server.Tests.Instance
sealed class InstanceTest
{
readonly IInstanceClient instanceClient;
readonly IInstanceManagerClient instanceManagerClient;
public InstanceTest(IInstanceClient instanceClient)
public InstanceTest(IInstanceClient instanceClient, IInstanceManagerClient instanceManagerClient)
{
this.instanceClient = instanceClient ?? throw new ArgumentNullException(nameof(instanceClient));
this.instanceManagerClient = instanceManagerClient ?? throw new ArgumentNullException(nameof(instanceManagerClient));
}
public async Task RunTests(CancellationToken cancellationToken)
{
var byondTests = new ByondTest(instanceClient.Byond, instanceClient.Jobs);
var configTests = new ConfigurationTest(instanceClient.Configuration, instanceClient.Metadata);
var byondTest = new ByondTest(instanceClient.Byond, instanceClient.Jobs);
var chatTest = new ChatTest(instanceClient.ChatBots, instanceManagerClient, instanceClient.Metadata.CloneMetadata());
var configTest = new ConfigurationTest(instanceClient.Configuration, instanceClient.Metadata);
var byondTest = byondTests.Run(cancellationToken);
await configTests.Run(cancellationToken).ConfigureAwait(false);
await byondTest.ConfigureAwait(false);
var byondTests = byondTest.Run(cancellationToken);
var chatTests = chatTest.Run(cancellationToken);
await configTest.Run(cancellationToken).ConfigureAwait(false);
await byondTests.ConfigureAwait(false);
await chatTests.ConfigureAwait(false);
}
}
}
@@ -30,7 +30,8 @@ namespace Tgstation.Server.Tests
{
Name = "TestInstance-" + ++counter,
Path = Path.Combine(testRootPath, Guid.NewGuid().ToString()),
Online = true
Online = true,
ChatBotLimit = 1
}, cancellationToken);
public async Task Run(CancellationToken cancellationToken)
@@ -115,7 +116,7 @@ namespace Tgstation.Server.Tests
Path = initialPath
}, cancellationToken), ErrorCode.InstanceRelocateOnline).ConfigureAwait(false);
var testSuite1 = new InstanceTest(instanceManagerClient.CreateClient(firstTest));
var testSuite1 = new InstanceTest(instanceManagerClient.CreateClient(firstTest), instanceManagerClient);
await testSuite1.RunTests(cancellationToken).ConfigureAwait(false);
//can regain permissions on instance without instance user