Skip to content

Commit

Permalink
Fix missing Blockquote enum value ( #31 ) & Add handling for missing …
Browse files Browse the repository at this point in the history
…enum values in the future
  • Loading branch information
niklasweimann committed Dec 31, 2023
1 parent 620eb47 commit 384ba33
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 3 deletions.
3 changes: 2 additions & 1 deletion src/RxTelegram.Bot/Api/BaseTelegramBot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using RxTelegram.Bot.Exceptions;
using RxTelegram.Bot.Interface.Validation;
using RxTelegram.Bot.Utils;
using RxTelegram.Bot.Utils.Converter;

namespace RxTelegram.Bot.Api;

Expand Down Expand Up @@ -46,7 +47,7 @@ public static JsonSerializerSettings JsonSerializerSettings
new InputFileConverter(),
new ChatIdConverter(),
new ChatBoostSourceConverter(),
new StringEnumConverter(new SnakeCaseNamingStrategy())
new UnknownStringEnumConverter(new SnakeCaseNamingStrategy())
};
return _jsonSerializerSettings = new JsonSerializerSettings
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,9 @@ public enum MessageEntityType
/// Inline custom emoji stickers
/// </summary>
CustomEmoji,

/// <summary>
/// block quotation
/// </summary>
Blockquote
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Newtonsoft.Json.Linq;
using RxTelegram.Bot.Interface.BaseTypes;

namespace RxTelegram.Bot.Utils;
namespace RxTelegram.Bot.Utils.Converter;

public class ChatIdConverter : JsonConverter<ChatId>
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Newtonsoft.Json;
using RxTelegram.Bot.Interface.BaseTypes.Requests.Attachments;

namespace RxTelegram.Bot.Utils;
namespace RxTelegram.Bot.Utils.Converter;

internal class InputFileConverter : JsonConverter<InputFile>
{
Expand Down
33 changes: 33 additions & 0 deletions src/RxTelegram.Bot/Utils/Converter/UnknownStringEnumConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace RxTelegram.Bot.Utils.Converter;

public class UnknownStringEnumConverter(NamingStrategy namingStrategy) : StringEnumConverter(namingStrategy)
{
public override object ReadJson(JsonReader reader, Type enumType, object existingValue, JsonSerializer serializer)
{
try
{
return base.ReadJson(reader, enumType, existingValue, serializer);
}
catch (Exception) when (enumType.IsEnum ||
enumType.IsGenericType &&
enumType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
enumType.GenericTypeArguments[0].IsEnum)
{
// Return null if it is a nullable enum and -1 if it is an enum to ensure that new values do not brake the bot
return reader.TokenType switch
{
JsonToken.Integer => Enum.ToObject(enumType, -1),
JsonToken.Null => null,
JsonToken.None => null,
JsonToken.String when enumType.IsGenericType && enumType.GetGenericTypeDefinition() == typeof(Nullable<>) => null,
JsonToken.String => Enum.ToObject(enumType, -1),
_ => throw new ArgumentOutOfRangeException()
};
}
}
}
75 changes: 75 additions & 0 deletions src/UnitTests/JsonConverters/UnknownStringEnumConverterTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NUnit.Framework;
using RxTelegram.Bot.Interface.BaseTypes.Enums;
using RxTelegram.Bot.Utils.Converter;

namespace RxTelegram.Bot.UnitTests.JsonConverters;

[TestFixture]
public class UnknownStringEnumConverterTest
{
private readonly JsonSerializerSettings _jsonSettings = new()
{
Converters =
{
new
UnknownStringEnumConverter(new
SnakeCaseNamingStrategy())
}
};

[Test]
[TestCase(@"""blockquote""", MessageEntityType.Blockquote)]
[TestCase(@"""Pre""", MessageEntityType.Pre)]
[TestCase(@"""code""", MessageEntityType.Code)]
[TestCase(@"""mention""", MessageEntityType.Mention)]
[TestCase(@"""url""", MessageEntityType.Url)]
[TestCase(@"""email""", MessageEntityType.Email)]
[TestCase(@"""bold""", MessageEntityType.Bold)]
[TestCase(@"""italic""", MessageEntityType.Italic)]
[TestCase(@"""spoiler""", MessageEntityType.Spoiler)]
[TestCase(@"""hashtag""", MessageEntityType.Hashtag)]
[TestCase(@"""bot_command""", MessageEntityType.BotCommand)]
[TestCase(@"""custom_emoji""", MessageEntityType.CustomEmoji)]
[TestCase(@"""text_link""", MessageEntityType.TextLink)]
[TestCase(@"""text_mention""", MessageEntityType.TextMention)]
[TestCase(@"""unknown""", MessageEntityType.Unknown)]
[TestCase(@"""doesnt_exist""", null)]
[TestCase("", null)]
[TestCase(" ", null)]
public void ReadJson_WithUnknownStringEnum_ReturnsEnumValueOrNull(string json, MessageEntityType? expected)
{
// Act
var result = JsonConvert.DeserializeObject<MessageEntityType?>(json, _jsonSettings);

// Assert
Assert.That(result, Is.EqualTo(expected));
}

[Test]
[TestCase(@"""blockquote""", (int)MessageEntityType.Blockquote)]
[TestCase(@"""Pre""", (int)MessageEntityType.Pre)]
[TestCase(@"""code""", (int)MessageEntityType.Code)]
[TestCase(@"""mention""", (int)MessageEntityType.Mention)]
[TestCase(@"""url""", (int)MessageEntityType.Url)]
[TestCase(@"""email""", (int)MessageEntityType.Email)]
[TestCase(@"""bold""", (int)MessageEntityType.Bold)]
[TestCase(@"""italic""", (int)MessageEntityType.Italic)]
[TestCase(@"""spoiler""", (int)MessageEntityType.Spoiler)]
[TestCase(@"""hashtag""", (int)MessageEntityType.Hashtag)]
[TestCase(@"""bot_command""", (int)MessageEntityType.BotCommand)]
[TestCase(@"""custom_emoji""", (int)MessageEntityType.CustomEmoji)]
[TestCase(@"""text_link""", (int)MessageEntityType.TextLink)]
[TestCase(@"""text_mention""", (int)MessageEntityType.TextMention)]
[TestCase(@"""unknown""", (int)MessageEntityType.Unknown)]
[TestCase(@"""doesnt_exist""", -1)]
public void ReadJson_WithUnknownStringEnum_ReturnsEnumValueOrNegativeValue(string json, int expected)
{
// Act
var result = JsonConvert.DeserializeObject<MessageEntityType>(json, _jsonSettings);

// Assert
Assert.That((int)result, Is.EqualTo(expected));
}
}

0 comments on commit 384ba33

Please sign in to comment.