From c78d843e515ab7f44ff6090d4f8e6ef9ea6acedc Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:21:48 +0300 Subject: [PATCH 01/90] Update README --- CHANGELOG.md | 4 ++++ README.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3414d4887..1864f0e72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] + +> [Bot API 7.0](https://core.telegram.org/bots/api#december-29-2023) (December 29, 2023) + ## [v20.0.0] - Unreleased > [Bot API 6.9](https://core.telegram.org/bots/api#september-22-2023) (September 22, 2023) diff --git a/README.md b/README.md index daf9c3f35..4b65d38ad 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # .NET Client for Telegram Bot API [![package](https://img.shields.io/nuget/vpre/Telegram.Bot.svg?label=Telegram.Bot&style=flat-square)](https://www.nuget.org/packages/Telegram.Bot) -[![Bot API Version](https://img.shields.io/badge/Bot%20API-6.9%20(September%2022,%202023)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#september-22-2023) +[![Bot API Version](https://img.shields.io/badge/Bot%20API-7.0%20(December%2029,%202023)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#december-29-2023) [![documentations](https://img.shields.io/badge/Documentations-Book-orange.svg?style=flat-square)](https://telegrambots.github.io/book/) [![telegram chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://t.me/joinchat/B35YY0QbLfd034CFnvCtCA) From ea17a00ef83e97c3d6a4837e0baee5781644caf3 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:03:14 +0300 Subject: [PATCH 02/90] Bump TargetFramework for test projects --- test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj | 4 ++-- test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj index 2d4277b76..909132e42 100644 --- a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj +++ b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj @@ -1,7 +1,7 @@ - net6.0 - 11 + net8.0 + 12.0 disable false diff --git a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj index fab480c82..e744fa28e 100644 --- a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj +++ b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj @@ -1,7 +1,7 @@ - net6.0 - 11 + net8.0 + 12.0 enable false From 525433dfd9aa3de5bf01daa7edf80882796df483 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:04:24 +0300 Subject: [PATCH 03/90] Bump references --- .../EnumSerializer.Generator.csproj | 4 +-- src/Telegram.Bot/Telegram.Bot.csproj | 11 ++++---- .../Telegram.Bot.Tests.Integ.csproj | 26 +++++++++---------- .../Telegram.Bot.Tests.Unit.csproj | 8 +++--- 4 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj b/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj index d95a01efa..3d7760956 100644 --- a/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj +++ b/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj @@ -14,9 +14,9 @@ - + - + diff --git a/src/Telegram.Bot/Telegram.Bot.csproj b/src/Telegram.Bot/Telegram.Bot.csproj index 883305b5a..918a34ffd 100644 --- a/src/Telegram.Bot/Telegram.Bot.csproj +++ b/src/Telegram.Bot/Telegram.Bot.csproj @@ -4,7 +4,6 @@ netstandard2.0;net6.0 11 enable - 7 True AllEnabledByDefault latest-recommended @@ -52,7 +51,7 @@ 'HttpClient.GetAsync(Uri, HttpCompletionOption, CancellationToken)' instead of 'HttpClient.GetAsync(string, HttpCompletionOption, CancellationToken)' --> $(NoWarn);CA1031 - $(NoWarn);MA0046;MA0048;MA0051 + $(NoWarn);MA0048;MA0051 @@ -70,7 +69,7 @@ - + @@ -79,9 +78,9 @@ - - - + + + diff --git a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj index 909132e42..48939b163 100644 --- a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj +++ b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj @@ -6,19 +6,19 @@ false - - - - - - - - - - - - - + + + + + + + + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj index e744fa28e..8704c7887 100644 --- a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj +++ b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj @@ -6,10 +6,10 @@ false - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive From 764f8d20820288f20d1bbeb165ac21d6a8170cf8 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 16:43:55 +0300 Subject: [PATCH 04/90] Reactions --- CHANGELOG.md | 13 ++++ .../Converters/ReactionTypeConverter.cs | 56 +++++++++++++++++ .../Messages/SetMessageReactionRequest.cs | 57 +++++++++++++++++ .../TelegramBotClientExtensions.ApiMethods.cs | 43 +++++++++++++ src/Telegram.Bot/Types/Chat.cs | 7 +++ src/Telegram.Bot/Types/Enums/UpdateType.cs | 26 +++++--- .../Types/MessageReactionCountUpdated.cs | 35 +++++++++++ .../Types/MessageReactionUpdated.cs | 53 ++++++++++++++++ src/Telegram.Bot/Types/ReactionCount.cs | 20 ++++++ src/Telegram.Bot/Types/ReactionType.cs | 62 ++++++++++++++++++ src/Telegram.Bot/Types/Update.cs | 51 ++++++++++----- .../EnumConverter/UpdateTypeConverterTests.cs | 63 ++++++++++++++----- 12 files changed, 446 insertions(+), 40 deletions(-) create mode 100644 src/Telegram.Bot/Converters/ReactionTypeConverter.cs create mode 100644 src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs create mode 100644 src/Telegram.Bot/Types/MessageReactionCountUpdated.cs create mode 100644 src/Telegram.Bot/Types/MessageReactionUpdated.cs create mode 100644 src/Telegram.Bot/Types/ReactionCount.cs create mode 100644 src/Telegram.Bot/Types/ReactionType.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1864f0e72..a4a845b6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/). > [Bot API 7.0](https://core.telegram.org/bots/api#december-29-2023) (December 29, 2023) +### Added + +- The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. +- Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` +and the field `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. +- Updates about reaction changes on a message with anonymous reactions, represented by the class `MessageReactionCountUpdated` +and the field `MessageReactionCount` in the class `Update`. The bot must explicitly allow the update to receive it. +- New enum values `MessageReaction`, `MessageReactionCount` for `UpdateType`. +- Type `ReactionCount`. +- Request type `SetMessageReactionRequest` that allows bots to react to messages. +- New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages. +- The field `AvailableReactions` to the class `Chat`. + ## [v20.0.0] - Unreleased > [Bot API 6.9](https://core.telegram.org/bots/api#september-22-2023) (September 22, 2023) diff --git a/src/Telegram.Bot/Converters/ReactionTypeConverter.cs b/src/Telegram.Bot/Converters/ReactionTypeConverter.cs new file mode 100644 index 000000000..382f7281b --- /dev/null +++ b/src/Telegram.Bot/Converters/ReactionTypeConverter.cs @@ -0,0 +1,56 @@ +using System.Reflection; +using Newtonsoft.Json.Linq; + +namespace Telegram.Bot.Converters; + +internal class ReactionTypeConverter : JsonConverter +{ + static readonly TypeInfo BaseType = typeof(ReactionType).GetTypeInfo(); + + public override bool CanWrite => false; + public override bool CanRead => true; + public override bool CanConvert(Type objectType) => + BaseType.IsAssignableFrom(objectType.GetTypeInfo()); + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + } + else + { + var jo = JObject.FromObject(value); + jo.WriteTo(writer); + } + } + + public override object? ReadJson( + JsonReader reader, + Type objectType, + object? existingValue, + JsonSerializer serializer) + { + var jo = JObject.Load(reader); + var type = jo["type"]?.Value(); + + if (type is null) + { + return null; + } + + var actualType = type switch + { + "emoji" => typeof(ReactionTypeEmoji), + "custom_emoji" => typeof(ReactionTypeCustomEmoji), + _ => throw new JsonSerializationException($"Unknown reaction type value of '{jo["type"]}'") + }; + + // Remove status because status property only has getter + jo.Remove("type"); + var value = Activator.CreateInstance(actualType)!; + serializer.Populate(jo.CreateReader(), value); + + return value; + } +} diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs new file mode 100644 index 000000000..f31822e4f --- /dev/null +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs @@ -0,0 +1,57 @@ +// ReSharper disable once CheckNamespace +using Telegram.Bot.Requests.Abstractions; + +namespace Telegram.Bot.Requests; + +/// +/// Use this method to change the chosen reactions on a message. Service messages can't be reacted to. +/// Automatically forwarded messages from a channel to its discussion group have the same +/// available reactions as messages in the channel. +/// Returns on success. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class SetMessageReactionRequest : RequestBase, + IChatTargetable +{ + /// + [JsonProperty(Required = Required.Always)] + public ChatId ChatId { get; } + + /// + /// Identifier of the target message. If the message belongs to a media group, the reaction + /// is set to the first non-deleted message in the group instead. + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } + + /// + /// New list of reaction types to set on the message. Currently, as non-premium users, bots can + /// set up to one reaction per message. A custom emoji reaction can be used if it is either + /// already present on the message or explicitly allowed by chat administrators. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ReactionType[]? Reaction { get; set; } + + /// + /// Pass to set the reaction with a big animation + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? IsBig { get; set; } + + /// + /// Initializes a new request with chatId and messageId + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Identifier of the target message. If the message belongs to a media group, the reaction + /// is set to the first non-deleted message in the group instead. + /// + public SetMessageReactionRequest(ChatId chatId, int messageId) + : base("setMessageReaction") + { + ChatId = chatId; + MessageId = messageId; + } +} diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 6484efb61..b067cfe87 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -1804,6 +1804,49 @@ await botClient.ThrowIfNull() cancellationToken) .ConfigureAwait(false); + /// + /// Use this method to change the chosen reactions on a message. Service messages can't be reacted to. + /// Automatically forwarded messages from a channel to its discussion group have the same + /// available reactions as messages in the channel. + /// + /// An instance of + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Identifier of the target message. If the message belongs to a media group, the reaction + /// is set to the first non-deleted message in the group instead. + /// + /// + /// New list of reaction types to set on the message. Currently, as non-premium users, bots can + /// set up to one reaction per message. A custom emoji reaction can be used if it is either + /// already present on the message or explicitly allowed by chat administrators. + /// + /// + /// Pass to set the reaction with a big animation + /// + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMessageReactionAsync( + this ITelegramBotClient botClient, + ChatId chatId, + int messageId, + ReactionType[]? reaction, + bool? isBig, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync( + new SetMessageReactionRequest(chatId, messageId) + { + Reaction = reaction, + IsBig = isBig, + }, + cancellationToken) + .ConfigureAwait(false); + /// /// Use this method to get a list of profile pictures for a user. /// diff --git a/src/Telegram.Bot/Types/Chat.cs b/src/Telegram.Bot/Types/Chat.cs index cf9415f58..67c6ff3d0 100644 --- a/src/Telegram.Bot/Types/Chat.cs +++ b/src/Telegram.Bot/Types/Chat.cs @@ -68,6 +68,13 @@ public class Chat [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public string[]? ActiveUsernames { get; set; } + /// + /// Optional. List of available reactions allowed in the chat. If omitted, then all emoji reactions are allowed. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ReactionType[]? AvailableReactions { get; set; } + /// /// Optional. Custom emoji identifier of emoji status of the other party in a private chat. /// Returned only in . diff --git a/src/Telegram.Bot/Types/Enums/UpdateType.cs b/src/Telegram.Bot/Types/Enums/UpdateType.cs index 15524bbdf..8cd249831 100644 --- a/src/Telegram.Bot/Types/Enums/UpdateType.cs +++ b/src/Telegram.Bot/Types/Enums/UpdateType.cs @@ -1,4 +1,4 @@ -namespace Telegram.Bot.Types.Enums; +namespace Telegram.Bot.Types.Enums; /// /// The type of an @@ -47,37 +47,47 @@ public enum UpdateType EditedChannelPost, /// - /// The contains an + /// The contains an /// ShippingQuery, /// - /// The contains an + /// The contains an /// PreCheckoutQuery, /// - /// The contains an + /// The contains an /// Poll, /// - /// The contains an + /// The contains an /// PollAnswer, /// - /// The contains an + /// The contains an /// MyChatMember, /// - /// The contains an + /// The contains an /// ChatMember, /// - /// The contains an + /// The contains an /// ChatJoinRequest, + + /// + /// The contains an + /// + MessageReaction, + + /// + /// The contains an + /// + MessageReactionCount, } diff --git a/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs b/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs new file mode 100644 index 000000000..65fc21d8f --- /dev/null +++ b/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs @@ -0,0 +1,35 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object represents reaction changes on a message with anonymous reactions. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageReactionCountUpdated +{ + /// + /// The chat containing the message + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Unique message identifier inside the chat + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } = default!; + + /// + /// Date of the change + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime Date { get; } = default!; + + /// + /// List of reactions that are present on the message + /// + [JsonProperty(Required = Required.Always)] + public ReactionCount[] Reactions { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/MessageReactionUpdated.cs b/src/Telegram.Bot/Types/MessageReactionUpdated.cs new file mode 100644 index 000000000..84db6082d --- /dev/null +++ b/src/Telegram.Bot/Types/MessageReactionUpdated.cs @@ -0,0 +1,53 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object represents a change of a reaction on a message performed by a user. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageReactionUpdated +{ + /// + /// The chat containing the message the user reacted to + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Unique identifier of the message inside the chat + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } = default!; + + /// + /// Optional.The user that changed the reaction, if the user isn't anonymous + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public User? User { get; set; } + + /// + /// Optional.The chat on behalf of which the reaction was changed, if the user is anonymous + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Chat? ActorChat { get; set; } + + /// + /// Date of the change + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime Date { get; } = default!; + + /// + /// Previous list of reaction types that were set by the user + /// + [JsonProperty(Required = Required.Always)] + public ReactionType[] OldReaction { get; } = default!; + + /// + /// New list of reaction types that have been set by the user + /// + [JsonProperty(Required = Required.Always)] + public ReactionType[] NewReaction { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/ReactionCount.cs b/src/Telegram.Bot/Types/ReactionCount.cs new file mode 100644 index 000000000..50f2c1f8b --- /dev/null +++ b/src/Telegram.Bot/Types/ReactionCount.cs @@ -0,0 +1,20 @@ +namespace Telegram.Bot.Types; + +/// +/// Represents a reaction added to a message along with the number of times it was added. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ReactionCount +{ + /// + /// Type of the reaction + /// + [JsonProperty(Required = Required.Always)] + public ReactionType Type { get; } = default!; + + /// + /// Number of times the reaction was added + /// + [JsonProperty(Required = Required.Always)] + public int TotalCount { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/ReactionType.cs b/src/Telegram.Bot/Types/ReactionType.cs new file mode 100644 index 000000000..3e1afee65 --- /dev/null +++ b/src/Telegram.Bot/Types/ReactionType.cs @@ -0,0 +1,62 @@ +using Telegram.Bot.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object describes the type of a reaction. Currently, it can be one of +/// +/// ReactionTypeEmoji +/// ReactionTypeCustomEmoji +/// +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +[JsonConverter(typeof(ReactionTypeConverter))] +public abstract class ReactionType +{ + /// + /// Type of the reaction + /// + [JsonProperty] + public abstract string Type { get; } +} + +/// +/// The reaction is based on an emoji. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ReactionTypeEmoji : ReactionType +{ + /// + /// Type of the reaction, always "emoji" + /// + public override string Type => "emoji"; + + /// + /// Reaction emoji. Currently, it can be one of "👍", "👎", "❤", "🔥", "🥰", "👏", "😁", + /// "🤔", "🤯", "😱", "🤬", "😢", "🎉", "🤩", "🤮", "💩", "🙏", "👌", "🕊", "🤡", "🥱", + /// "🥴", "😍", "🐳", "❤‍🔥", "🌚", "🌭", "💯", "🤣", "⚡", "🍌", "🏆", "💔", "🤨", + /// "😐", "🍓", "🍾", "💋", "🖕", "😈", "😴", "😭", "🤓", "👻", "👨‍💻", "👀", "🎃", + /// "🙈", "😇", "😨", "🤝", "✍", "🤗", "🫡", "🎅", "🎄", "☃", "💅", "🤪", "🗿", "🆒", + /// "💘", "🙉", "🦄", "😘", "💊", "🙊", "😎", "👾", "🤷‍♂", "🤷", "🤷‍♀", "😡" + /// + [JsonProperty(Required = Required.Always)] + public string Emoji { get; } = default!; +} + +/// +/// The reaction is based on an emoji. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ReactionTypeCustomEmoji : ReactionType +{ + /// + /// Type of the reaction, always "custom_emoji" + /// + public override string Type => "custom_emoji"; + + /// + /// Custom emoji identifier + /// + [JsonProperty(Required = Required.Always)] + public string CustomEmojiId { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/Update.cs b/src/Telegram.Bot/Types/Update.cs index 575ac82a7..0be985b66 100644 --- a/src/Telegram.Bot/Types/Update.cs +++ b/src/Telegram.Bot/Types/Update.cs @@ -46,6 +46,23 @@ public class Update [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public Message? EditedChannelPost { get; set; } + /// + /// Optional. A reaction to a message was changed by a user. The bot must be an administrator + /// in the chat and must explicitly specify "" in the list + /// of AllowedUpdates to receive these updates. + /// The update isn't received for reactions set by bots. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public MessageReactionUpdated? MessageReaction { get; set; } + + /// + /// Optional. Reactions to a message with anonymous reactions were changed. The bot must + /// be an administrator in the chat and must explicitly specify "" + /// in the list of AllowedUpdates to receive these updates. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public MessageReactionCountUpdated? MessageReactionCount { get; set; } + /// /// Optional. New incoming inline query /// @@ -98,7 +115,7 @@ public class Update /// /// Optional. A chat member's status was updated in a chat. The bot must be an administrator in the chat - /// and must explicitly specify “” in the list of allowed_updates to + /// and must explicitly specify “” in the list of AllowedUpdates to /// receive these updates. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -119,20 +136,22 @@ public class Update /// public UpdateType Type => this switch { - { Message: { } } => UpdateType.Message, - { EditedMessage: { } } => UpdateType.EditedMessage, - { InlineQuery: { } } => UpdateType.InlineQuery, - { ChosenInlineResult: { } } => UpdateType.ChosenInlineResult, - { CallbackQuery: { } } => UpdateType.CallbackQuery, - { ChannelPost: { } } => UpdateType.ChannelPost, - { EditedChannelPost: { } } => UpdateType.EditedChannelPost, - { ShippingQuery: { } } => UpdateType.ShippingQuery, - { PreCheckoutQuery: { } } => UpdateType.PreCheckoutQuery, - { Poll: { } } => UpdateType.Poll, - { PollAnswer: { } } => UpdateType.PollAnswer, - { MyChatMember: { } } => UpdateType.MyChatMember, - { ChatMember: { } } => UpdateType.ChatMember, - { ChatJoinRequest: { } } => UpdateType.ChatJoinRequest, - _ => UpdateType.Unknown + { Message: { } } => UpdateType.Message, + { EditedMessage: { } } => UpdateType.EditedMessage, + { InlineQuery: { } } => UpdateType.InlineQuery, + { ChosenInlineResult: { } } => UpdateType.ChosenInlineResult, + { CallbackQuery: { } } => UpdateType.CallbackQuery, + { ChannelPost: { } } => UpdateType.ChannelPost, + { EditedChannelPost: { } } => UpdateType.EditedChannelPost, + { ShippingQuery: { } } => UpdateType.ShippingQuery, + { PreCheckoutQuery: { } } => UpdateType.PreCheckoutQuery, + { Poll: { } } => UpdateType.Poll, + { PollAnswer: { } } => UpdateType.PollAnswer, + { MyChatMember: { } } => UpdateType.MyChatMember, + { ChatMember: { } } => UpdateType.ChatMember, + { ChatJoinRequest: { } } => UpdateType.ChatJoinRequest, + { MessageReaction: { } } => UpdateType.MessageReaction, + { MessageReactionCount: { } } => UpdateType.MessageReactionCount, + _ => UpdateType.Unknown }; } diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs index ba3ade3b3..6a031781a 100644 --- a/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Telegram.Bot.Types.Enums; @@ -8,22 +10,25 @@ namespace Telegram.Bot.Tests.Unit.EnumConverter; public class UpdateTypeConverterTests { + [Fact] + public void Should_Verify_All_UpdateType_Members() + { + List updateTypeMembers = Enum + .GetNames() + .OrderBy(x => x) + .ToList(); + List updateTypeDataMembers = new UpdateTypeData() + .Select(x => Enum.GetName(typeof(UpdateType), x[0])) + .OrderBy(x => x) + .ToList()!; + + Assert.Equal(updateTypeMembers.Count, updateTypeDataMembers.Count); + Assert.Equal(updateTypeMembers, updateTypeDataMembers); + } + + [Theory] - [InlineData(UpdateType.Unknown, "unknown")] - [InlineData(UpdateType.Message, "message")] - [InlineData(UpdateType.InlineQuery, "inline_query")] - [InlineData(UpdateType.ChosenInlineResult, "chosen_inline_result")] - [InlineData(UpdateType.CallbackQuery, "callback_query")] - [InlineData(UpdateType.EditedMessage, "edited_message")] - [InlineData(UpdateType.ChannelPost, "channel_post")] - [InlineData(UpdateType.EditedChannelPost, "edited_channel_post")] - [InlineData(UpdateType.ShippingQuery, "shipping_query")] - [InlineData(UpdateType.PreCheckoutQuery, "pre_checkout_query")] - [InlineData(UpdateType.Poll, "poll")] - [InlineData(UpdateType.PollAnswer, "poll_answer")] - [InlineData(UpdateType.MyChatMember, "my_chat_member")] - [InlineData(UpdateType.ChatMember, "chat_member")] - [InlineData(UpdateType.ChatJoinRequest, "chat_join_request")] + [ClassData(typeof(UpdateTypeData))] public void Should_Convert_UpdateType_To_String(UpdateType updateType, string value) { Update update = new(updateType); @@ -38,7 +43,7 @@ public void Should_Convert_UpdateType_To_String(UpdateType updateType, string va } [Theory] - [InlineData(UpdateType.Unknown, "unknown")] + [ClassData(typeof(UpdateTypeData))] public void Should_Convert_String_To_UpdateType(UpdateType updateType, string value) { Update expectedResult = new(updateType); @@ -77,4 +82,30 @@ public void Should_Throw_NotSupportedException_For_Incorrect_UpdateType() [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] record Update([property: JsonProperty(Required = Required.Always)] UpdateType Type); + + private class UpdateTypeData : IEnumerable + { + public IEnumerator GetEnumerator() + { + yield return new object[] { UpdateType.Unknown, "unknown" }; + yield return new object[] { UpdateType.Message, "message" }; + yield return new object[] { UpdateType.InlineQuery, "inline_query" }; + yield return new object[] { UpdateType.ChosenInlineResult, "chosen_inline_result" }; + yield return new object[] { UpdateType.CallbackQuery, "callback_query" }; + yield return new object[] { UpdateType.EditedMessage, "edited_message" }; + yield return new object[] { UpdateType.ChannelPost, "channel_post" }; + yield return new object[] { UpdateType.EditedChannelPost, "edited_channel_post" }; + yield return new object[] { UpdateType.ShippingQuery, "shipping_query" }; + yield return new object[] { UpdateType.PreCheckoutQuery, "pre_checkout_query" }; + yield return new object[] { UpdateType.Poll, "poll" }; + yield return new object[] { UpdateType.PollAnswer, "poll_answer" }; + yield return new object[] { UpdateType.MyChatMember, "my_chat_member" }; + yield return new object[] { UpdateType.ChatMember, "chat_member" }; + yield return new object[] { UpdateType.ChatJoinRequest, "chat_join_request" }; + yield return new object[] { UpdateType.MessageReaction, "message_reaction" }; + yield return new object[] { UpdateType.MessageReactionCount, "message_reaction_count" }; + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); + } } From 0f0ac76b3e3249a7631f121cf7e18df5e01b4de9 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 18:37:27 +0300 Subject: [PATCH 05/90] Address feedback: replace { } with not null in UpdateType matching. --- src/Telegram.Bot/Types/Update.cs | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Telegram.Bot/Types/Update.cs b/src/Telegram.Bot/Types/Update.cs index 0be985b66..4ab6fa150 100644 --- a/src/Telegram.Bot/Types/Update.cs +++ b/src/Telegram.Bot/Types/Update.cs @@ -136,22 +136,22 @@ public class Update /// public UpdateType Type => this switch { - { Message: { } } => UpdateType.Message, - { EditedMessage: { } } => UpdateType.EditedMessage, - { InlineQuery: { } } => UpdateType.InlineQuery, - { ChosenInlineResult: { } } => UpdateType.ChosenInlineResult, - { CallbackQuery: { } } => UpdateType.CallbackQuery, - { ChannelPost: { } } => UpdateType.ChannelPost, - { EditedChannelPost: { } } => UpdateType.EditedChannelPost, - { ShippingQuery: { } } => UpdateType.ShippingQuery, - { PreCheckoutQuery: { } } => UpdateType.PreCheckoutQuery, - { Poll: { } } => UpdateType.Poll, - { PollAnswer: { } } => UpdateType.PollAnswer, - { MyChatMember: { } } => UpdateType.MyChatMember, - { ChatMember: { } } => UpdateType.ChatMember, - { ChatJoinRequest: { } } => UpdateType.ChatJoinRequest, - { MessageReaction: { } } => UpdateType.MessageReaction, - { MessageReactionCount: { } } => UpdateType.MessageReactionCount, - _ => UpdateType.Unknown + { Message: not null } => UpdateType.Message, + { EditedMessage: not null } => UpdateType.EditedMessage, + { ChannelPost: not null } => UpdateType.ChannelPost, + { EditedChannelPost: not null } => UpdateType.EditedChannelPost, + { MessageReaction: not null } => UpdateType.MessageReaction, + { MessageReactionCount: not null } => UpdateType.MessageReactionCount, + { InlineQuery: not null } => UpdateType.InlineQuery, + { ChosenInlineResult: not null } => UpdateType.ChosenInlineResult, + { CallbackQuery: not null } => UpdateType.CallbackQuery, + { ShippingQuery: not null } => UpdateType.ShippingQuery, + { PreCheckoutQuery: not null } => UpdateType.PreCheckoutQuery, + { Poll: not null } => UpdateType.Poll, + { PollAnswer: not null } => UpdateType.PollAnswer, + { MyChatMember: not null } => UpdateType.MyChatMember, + { ChatMember: not null } => UpdateType.ChatMember, + { ChatJoinRequest: not null } => UpdateType.ChatJoinRequest, + _ => UpdateType.Unknown }; } From a866e73db3f17e68a679bb96d46c8d50d067ded3 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 19:52:51 +0300 Subject: [PATCH 06/90] Replies 2.0: Add ExternalReplyInfo and TextQuote --- src/Telegram.Bot/Types/ExternalReplyInfo.cs | 149 ++++++++++++++++++++ src/Telegram.Bot/Types/Message.cs | 10 +- src/Telegram.Bot/Types/TextQuote.cs | 33 +++++ 3 files changed, 187 insertions(+), 5 deletions(-) create mode 100644 src/Telegram.Bot/Types/ExternalReplyInfo.cs create mode 100644 src/Telegram.Bot/Types/TextQuote.cs diff --git a/src/Telegram.Bot/Types/ExternalReplyInfo.cs b/src/Telegram.Bot/Types/ExternalReplyInfo.cs new file mode 100644 index 000000000..9d06fbf8e --- /dev/null +++ b/src/Telegram.Bot/Types/ExternalReplyInfo.cs @@ -0,0 +1,149 @@ +using Telegram.Bot.Types.Payments; + +namespace Telegram.Bot.Types; + +/// +/// This object contains information about a message that is being replied to, which may come from another chat or forum topic. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ExternalReplyInfo +{ + /// + /// Origin of the message replied to by the given message + /// + [JsonProperty(Required = Required.Always)] + public MessageOrigin Origin { get; } = default!; + + /// + /// Optional.Chat the original message belongs to.Available only if the chat is a supergroup or a channel. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Chat? Chat { get; set; } + + /// + /// Optional.Unique message identifier inside the original chat.Available only if the original chat + /// is a supergroup or a channel. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageId { get; set; } + + /// + /// Optional.Options used for link preview generation for the original message, if it is a text message + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public LinkPreviewOptions LinkPreviewOptions { get; set; } + + /// + /// Optional. Message is an animation, information about the animation + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Animation? Animation { get; set; } + + /// + /// Optional. Message is an audio file, information about the file + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Audio? Audio { get; set; } + + /// + /// Optional. Message is a general file, information about the file + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Document? Document { get; set; } + + /// + /// Optional. Message is a photo, available sizes of the photo + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public PhotoSize[]? Photo { get; set; } + + /// + /// Optional. Message is a sticker, information about the sticker + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Sticker? Sticker { get; set; } + + /// + /// Optional. Message is a forwarded story + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Story? Story { get; set; } + + /// + /// Optional. Message is a video, information about the video + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Video? Video { get; set; } + + /// + /// Optional. Message is a video note, information about the video message + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public VideoNote? VideoNote { get; set; } + + /// + /// Optional. Message is a voice message, information about the file + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Voice? Voice { get; set; } + + /// + /// Optional. , if the message media is covered by a spoiler animation + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? HasMediaSpoiler { get; set; } + + /// + /// Optional. Message is a shared contact, information about the contact + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Contact? Contact { get; set; } + + /// + /// Optional. Message is a dice with random value + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Dice? Dice { get; set; } + + /// + /// Optional. Message is a game, information about the game. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Game? Game { get; set; } + + /// + /// Optional. Message is a scheduled giveaway, information about the giveaway + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Giveaway? Giveaway { get; set; } + + /// + /// Optional.A giveaway with public winners was completed + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public GiveawayWinners? GiveawayWinners { get; set; } + + /// + /// Optional. Message is an invoice for a payment, information about the invoice. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Invoice? Invoice { get; set; } + + /// + /// Optional. Message is a shared location, information about the location + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Location? Location { get; set; } + + /// + /// Optional. Message is a native poll, information about the poll + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Poll? Poll { get; set; } + + /// + /// Optional. Message is a venue, information about the venue + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Venue? Venue { get; set; } +} diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index 4602fd24c..fb52266e3 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -79,17 +79,17 @@ public class Message public int? ForwardFromMessageId { get; set; } /// - /// Optional. For messages forwarded from channels, signature of the post author if present + /// Optional. Information about the message that is being replied to, which may come from + /// another chat or forum topic /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public string? ForwardSignature { get; set; } + public ExternalReplyInfo? ExternalReply { get; set; } /// - /// Optional. Sender's name for messages forwarded from users who disallow adding a link to their account in - /// forwarded messages + /// Optional. For replies that quote part of the original message, the quoted part of the message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public string? ForwardSenderName { get; set; } + public TextQuote? Quote { get; set; } /// /// Optional. For forwarded messages, date the original message was sent diff --git a/src/Telegram.Bot/Types/TextQuote.cs b/src/Telegram.Bot/Types/TextQuote.cs new file mode 100644 index 000000000..fc3cba126 --- /dev/null +++ b/src/Telegram.Bot/Types/TextQuote.cs @@ -0,0 +1,33 @@ +namespace Telegram.Bot.Types; + +/// +/// This object contains information about the quoted part of a message that is replied to by the given message. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class TextQuote +{ + /// + /// Text of the quoted part of a message that is replied to by the given message + /// + [JsonProperty(Required = Required.Always)] + public string Text { get; } = default!; + + /// + /// Optional. Special entities that appear in the quote. Currently, only bold, italic, underline, + /// strikethrough, spoiler, and custom_emoji entities are kept in quotes. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public MessageEntity[]? Entities { get; set; } + + /// + /// Approximate quote position in the original message in UTF-16 code units as specified by the sender + /// + [JsonProperty(Required = Required.Always)] + public int Position { get; } = default!; + + /// + /// Optional.True, if the quote was chosen manually by the message sender.Otherwise, the quote was added automatically by the server. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool IsManual { get; set; } +} From 5de18c30f7393d19e8e681d0eb6c2e405d259a6a Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:46:09 +0300 Subject: [PATCH 07/90] Replies 2.0: ReplyParameters --- .../Requests/Abstractions/Documentation.cs | 9 +- .../Messages/CopyMessageRequest.cs | 8 +- .../Messages/Location/SendLocationRequest.cs | 12 +- .../Messages/Location/SendVenueRequest.cs | 8 +- .../Messages/SendAnimationRequest.cs | 8 +- .../Messages/SendAudioRequest.cs | 8 +- .../Messages/SendContactRequest.cs | 8 +- .../Messages/SendDiceRequest.cs | 8 +- .../Messages/SendDocumentRequest.cs | 8 +- .../Messages/SendMediaGroupRequest.cs | 8 +- .../Messages/SendMessageRequest.cs | 8 +- .../Messages/SendPhotoRequest.cs | 8 +- .../Messages/SendPollRequest.cs | 8 +- .../Messages/SendVideoNoteRequest.cs | 8 +- .../Messages/SendVideoRequest.cs | 8 +- .../Messages/SendVoiceRequest.cs | 8 +- .../Requests/Games/SendGameRequest.cs | 8 +- .../Requests/Payments/SendInvoiceRequest.cs | 8 +- .../Requests/Stickers/SendStickerRequest.cs | 8 +- .../TelegramBotClientExtensions.ApiMethods.cs | 232 ++++++------------ src/Telegram.Bot/Types/Message.cs | 32 +-- src/Telegram.Bot/Types/ReplyParameters.cs | 56 +++++ 22 files changed, 170 insertions(+), 307 deletions(-) create mode 100644 src/Telegram.Bot/Types/ReplyParameters.cs diff --git a/src/Telegram.Bot/Requests/Abstractions/Documentation.cs b/src/Telegram.Bot/Requests/Abstractions/Documentation.cs index 3202bd265..ff2d67e2b 100644 --- a/src/Telegram.Bot/Requests/Abstractions/Documentation.cs +++ b/src/Telegram.Bot/Requests/Abstractions/Documentation.cs @@ -57,14 +57,9 @@ internal static class Documentation static readonly object DisableNotification; /// - /// If the message is a reply, ID of the original message + /// Description of the message to reply to /// - static readonly object ReplyToMessageId; - - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// - static readonly object AllowSendingWithoutReply; + static readonly object ReplyParameters; /// /// Thumbnail of the file sent; can be ignored if thumbnail generation for the file is supported diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs index 2712b17f3..c20c98b88 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs @@ -65,13 +65,9 @@ public class CopyMessageRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs index 60089f584..b33a21e97 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs @@ -62,17 +62,9 @@ public class SendLocationRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// - /// If the message is a reply, ID of the original message - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs index 9b1613cf8..5fa5a5923 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs @@ -78,13 +78,9 @@ public class SendVenueRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs index 8a926e368..4a3ed2e83 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs @@ -85,13 +85,9 @@ public class SendAnimationRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs index 61f7e4857..fae5e36a1 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs @@ -79,13 +79,9 @@ public class SendAudioRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs index a3f219054..4aebb182f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs @@ -52,13 +52,9 @@ public class SendContactRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs index 0f62b3489..fbb817592 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs @@ -38,13 +38,9 @@ public class SendDiceRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs index e0996bbd2..556223ebc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs @@ -67,13 +67,9 @@ public class SendDocumentRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs index 9283d291f..f5769330d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs @@ -38,13 +38,9 @@ public class SendMediaGroupRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// /// Initializes a request with chatId and media diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs index 68ea39c0c..f330759a0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs @@ -50,13 +50,9 @@ public class SendMessageRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs index a119f9cb0..6052c11c6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs @@ -62,13 +62,9 @@ public class SendPhotoRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs index acaeed7dd..cc837db05 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs @@ -111,13 +111,9 @@ public class SendPollRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs index df0c2f52e..f5b249928 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs @@ -56,13 +56,9 @@ public class SendVideoNoteRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs index 64747f53e..10c909954 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs @@ -91,13 +91,9 @@ public class SendVideoRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs index 8cbed9619..da9600e3b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs @@ -63,13 +63,9 @@ public class SendVoiceRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs index dc5a6d125..3e9094569 100644 --- a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs @@ -40,13 +40,9 @@ public class SendGameRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs index 89d81738d..9ae0e304d 100644 --- a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs @@ -178,13 +178,9 @@ public class SendInvoiceRequest : RequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs index 02790c5da..e4b34bf6e 100644 --- a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs @@ -47,13 +47,9 @@ public class SendStickerRequest : FileRequestBase, IChatTargetable [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ProtectContent { get; set; } - /// + /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ReplyToMessageId { get; set; } - - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? AllowSendingWithoutReply { get; set; } + public ReplyParameters? ReplyParameters { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index b067cfe87..8f2c68ab0 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -298,10 +298,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -322,8 +319,7 @@ public static async Task SendTextMessageAsync( bool? disableWebPagePreview = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -331,13 +327,13 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendMessageRequest(chatId, text) { + MessageThreadId = messageThreadId, ParseMode = parseMode, Entities = entities, DisableWebPagePreview = disableWebPagePreview, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, MessageThreadId = messageThreadId, }, @@ -426,10 +422,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -451,8 +444,7 @@ public static async Task CopyMessageAsync( IEnumerable? captionEntities = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -463,10 +455,9 @@ await botClient.ThrowIfNull() Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, - ReplyToMessageId = replyToMessageId, DisableNotification = disableNotification, ProtectContent = protectContent, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, MessageThreadId = messageThreadId, }, @@ -511,10 +502,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -536,8 +524,7 @@ public static async Task SendPhotoAsync( bool? hasSpoiler = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -545,16 +532,15 @@ await botClient.ThrowIfNull(). MakeRequestAsync( request: new SendPhotoRequest(chatId, photo) { + MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, HasSpoiler = hasSpoiler, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -602,10 +588,7 @@ await botClient.ThrowIfNull(). /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -630,8 +613,7 @@ public static async Task SendAudioAsync( InputFile? thumbnail = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -639,6 +621,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendAudioRequest(chatId, audio) { + MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, @@ -648,10 +631,8 @@ await botClient.ThrowIfNull() Thumbnail = thumbnail, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -701,10 +682,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -727,8 +705,7 @@ public static async Task SendDocumentAsync( bool? disableContentTypeDetection = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -736,6 +713,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendDocumentRequest(chatId, document) { + MessageThreadId = messageThreadId, Thumbnail = thumbnail, Caption = caption, ParseMode = parseMode, @@ -743,10 +721,8 @@ await botClient.ThrowIfNull() DisableContentTypeDetection = disableContentTypeDetection, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -800,10 +776,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -830,8 +803,7 @@ public static async Task SendVideoAsync( bool? supportsStreaming = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -839,6 +811,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendVideoRequest(chatId, video) { + MessageThreadId = messageThreadId, Duration = duration, Width = width, Height = height, @@ -850,10 +823,8 @@ await botClient.ThrowIfNull() SupportsStreaming = supportsStreaming, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -906,10 +877,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -935,8 +903,7 @@ public static async Task SendAnimationAsync( bool? hasSpoiler = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -944,6 +911,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendAnimationRequest(chatId, animation) { + MessageThreadId = messageThreadId, Duration = duration, Width = width, Height = height, @@ -954,10 +922,8 @@ await botClient.ThrowIfNull() HasSpoiler = hasSpoiler, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -997,10 +963,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1022,8 +985,7 @@ public static async Task SendVoiceAsync( int? duration = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1031,16 +993,15 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendVoiceRequest(chatId, voice) { + MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, Duration = duration, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -1076,10 +1037,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1100,8 +1058,7 @@ public static async Task SendVideoNoteAsync( InputFile? thumbnail = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1109,15 +1066,14 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendVideoNoteRequest(chatId, videoNote) { + MessageThreadId = messageThreadId, Duration = duration, Length = length, Thumbnail = thumbnail, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -1140,10 +1096,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// @@ -1155,19 +1108,17 @@ public static async Task SendMediaGroupAsync( int? messageThreadId = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendMediaGroupRequest(chatId, media) { + MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, - MessageThreadId = messageThreadId, + ReplyParameters = replyParameters, }, cancellationToken ) @@ -1201,10 +1152,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1226,8 +1174,7 @@ public static async Task SendLocationAsync( int? proximityAlertRadius = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1235,15 +1182,14 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendLocationRequest(chatId, latitude, longitude) { + MessageThreadId = messageThreadId, LivePeriod = livePeriod, Heading = heading, ProximityAlertRadius = proximityAlertRadius, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -1456,10 +1402,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1485,8 +1428,7 @@ public static async Task SendVenueAsync( string? googlePlaceType = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1500,8 +1442,7 @@ await botClient.ThrowIfNull() GooglePlaceType = googlePlaceType, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, MessageThreadId = messageThreadId, }, @@ -1528,10 +1469,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1552,8 +1490,7 @@ public static async Task SendContactAsync( string? vCard = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1565,8 +1502,7 @@ await botClient.ThrowIfNull() Vcard = vCard, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, MessageThreadId = messageThreadId, }, @@ -1627,10 +1563,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1659,8 +1592,7 @@ public static async Task SendPollAsync( bool? isClosed = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1668,6 +1600,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendPollRequest(chatId, question, options) { + MessageThreadId = messageThreadId, IsAnonymous = isAnonymous, Type = type, AllowsMultipleAnswers = allowsMultipleAnswers, @@ -1680,10 +1613,8 @@ await botClient.ThrowIfNull() IsClosed = isClosed, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -1712,10 +1643,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -1733,8 +1661,7 @@ public static async Task SendDiceAsync( Emoji? emoji = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -1742,13 +1669,12 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendDiceRequest(chatId) { + MessageThreadId = messageThreadId, Emoji = emoji, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -4045,13 +3971,7 @@ await botClient.ThrowIfNull() /// /// Protects the contents of sent messages from forwarding and saving /// - /// - /// If the message is a reply, ID of the original message - /// - /// - /// Pass , if the message should be sent even if the specified - /// replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -4072,8 +3992,7 @@ public static async Task SendStickerAsync( string? emoji = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, IReplyMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -4081,13 +4000,12 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendStickerRequest(chatId, sticker) { + MessageThreadId = messageThreadId, + Emoji = emoji, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, - Emoji = emoji, }, cancellationToken: cancellationToken ) @@ -4686,10 +4604,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -4727,8 +4642,7 @@ public static async Task SendInvoiceAsync( bool? isFlexible = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, InlineKeyboardMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -4744,6 +4658,7 @@ await botClient.ThrowIfNull() // ReSharper disable once PossibleMultipleEnumeration prices) { + MessageThreadId = messageThreadId, MaxTipAmount = maxTipAmount, SuggestedTipAmounts = suggestedTipAmounts, StartParameter = startParameter, @@ -4761,10 +4676,8 @@ await botClient.ThrowIfNull() IsFlexible = isFlexible, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -5012,10 +4925,7 @@ await botClient.ThrowIfNull() /// Sends the message silently. Users will receive a notification with no sound /// /// Protects the contents of sent messages from forwarding and saving - /// If the message is a reply, ID of the original message - /// - /// Pass , if the message should be sent even if the specified replied-to message is not found - /// + /// Description of the message to reply to /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -5033,8 +4943,7 @@ public static async Task SendGameAsync( int? messageThreadId = default, bool? disableNotification = default, bool? protectContent = default, - int? replyToMessageId = default, - bool? allowSendingWithoutReply = default, + ReplyParameters? replyParameters = default, InlineKeyboardMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -5042,12 +4951,11 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new SendGameRequest(chatId, gameShortName) { + MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, - ReplyToMessageId = replyToMessageId, - AllowSendingWithoutReply = allowSendingWithoutReply, + ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index fb52266e3..a7cbd4fbb 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -66,17 +66,18 @@ public class Message public bool? IsTopicMessage { get; set; } /// - /// Optional. For messages forwarded from channels or from anonymous administrators, information about the - /// original sender chat + /// Optional. , if the message is a channel post that was automatically forwarded to the connected + /// discussion group /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public Chat? ForwardFromChat { get; set; } + public bool? IsAutomaticForward { get; set; } /// - /// Optional. For messages forwarded from channels, identifier of the original message in the channel + /// Optional. For replies, the original message. Note that the object in this field + /// will not contain further fields even if it itself is a reply. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? ForwardFromMessageId { get; set; } + public Message? ReplyToMessage { get; set; } /// /// Optional. Information about the message that is being replied to, which may come from @@ -91,27 +92,6 @@ public class Message [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public TextQuote? Quote { get; set; } - /// - /// Optional. For forwarded messages, date the original message was sent - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime? ForwardDate { get; set; } - - /// - /// Optional. , if the message is a channel post that was automatically forwarded to the connected - /// discussion group - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? IsAutomaticForward { get; set; } - - /// - /// Optional. For replies, the original message. Note that the object in this field - /// will not contain further fields even if it itself is a reply. - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public Message? ReplyToMessage { get; set; } - /// /// Optional. Bot through which the message was sent /// diff --git a/src/Telegram.Bot/Types/ReplyParameters.cs b/src/Telegram.Bot/Types/ReplyParameters.cs new file mode 100644 index 000000000..0c763cce8 --- /dev/null +++ b/src/Telegram.Bot/Types/ReplyParameters.cs @@ -0,0 +1,56 @@ +namespace Telegram.Bot.Types; + +/// +/// Describes reply parameters for the message that is being sent. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ReplyParameters +{ + /// + /// Identifier of the message that will be replied to in the current chat, or in the chat if it is specified + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } + + /// + /// Optional. If the message to be replied to is from a different chat, unique identifier for the + /// chat or username of the channel (in the format @channelusername) + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ChatId? ChatId { get; set; } + + /// + /// Optional. Pass if the message should be sent even if the specified message + /// to be replied to is not found; can be used only for replies in the same chat and forum topic. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? AllowSendingWithoutReply { get; set; } + + /// + /// Optional. Quoted part of the message to be replied to; 0-1024 characters after entities parsing. + /// The quote must be an exact substring of the message to be replied to, including bold, italic, + /// underline, strikethrough, spoiler, and custom_emoji entities. + /// The message will fail to send if the quote isn't found in the original message. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? Quote { get; set; } + + /// + /// Optional. Mode for parsing entities in the quote. See formatting options for more details. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? QuoteParseMode { get; set; } + + /// + /// Optional. A JSON-serialized list of special entities that appear in the quote. + /// It can be specified instead of . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public MessageEntity[]? QuoteEntities { get; set; } + + /// + /// Optional. Position of the quote in the original message in UTF-16 code units + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? QuotePosition { get; set; } +} From 31b7c65d9ccfe74faffa1abe509561c11a949f47 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:57:49 +0300 Subject: [PATCH 08/90] Replies 2.0: updata CHANGELOG --- CHANGELOG.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4a845b6c..1401713b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,14 +29,61 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. - Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` -and the field `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. +and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. - Updates about reaction changes on a message with anonymous reactions, represented by the class `MessageReactionCountUpdated` -and the field `MessageReactionCount` in the class `Update`. The bot must explicitly allow the update to receive it. +and the property `MessageReactionCount` in the class `Update`. The bot must explicitly allow the update to receive it. - New enum values `MessageReaction`, `MessageReactionCount` for `UpdateType`. - Type `ReactionCount`. - Request type `SetMessageReactionRequest` that allows bots to react to messages. - New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages. - The field `AvailableReactions` to the class `Chat`. +- The class `ExternalReplyInfo` and the property `ExternalReply` of type `ExternalReplyInfo` to the class `Message`, +containing information about a message that is replied to by the current message, but can be from another chat or forum topic. +- Added the class `TextQuote` and the property `Quote` of type `TextQuote` to the class `Message`, +which contains the part of the replied message text or caption that is quoted in the current message. +- The class `ReplyParameters`. + +### Changed + +- Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods + - `ITelegramBotClient.CopyMessageAsync`, + - `ITelegramBotClient.SendMessageAsync`, + - `ITelegramBotClient.SendPhotoAsync`, + - `ITelegramBotClient.SendVideoAsync`, + - `ITelegramBotClient.SendAnimationAsync`, + - `ITelegramBotClient.SendAudioAsync`, + - `ITelegramBotClient.SendDocumentAsync`, + - `ITelegramBotClient.SendStickerAsync`, + - `ITelegramBotClient.SendVideoNoteAsync`, + - `ITelegramBotClient.SendVoiceAsync`, + - `ITelegramBotClient.SendLocationAsync`, + - `ITelegramBotClient.SendVenueAsync`, + - `ITelegramBotClient.SendContactAsync`, + - `ITelegramBotClient.SendPollAsync`, + - `ITelegramBotClient.SendDiceAsync`, + - `ITelegramBotClient.SendInvoiceAsync`, + - `ITelegramBotClient.SendGameAsync`, + - `ITelegramBotClient.SendMediaGroupAsync` +- Replaced properties `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the request classes + - `CopyMessageRequest`, + - `SendMessageRequest`, + - `SendPhotoRequest`, + - `SendVideoRequest`, + - `SendAnimationRequest`, + - `SendAudioRequest`, + - `SendDocumentRequest`, + - `SendStickerRequest`, + - `SendVideoNoteRequest`, + - `SendVoiceRequest`, + - `SendLocationRequest`, + - `SendVenueRequest`, + - `SendContactRequest`, + - `SendPollRequest`, + - `SendDiceRequest`, + - `SendInvoiceRequest`, + - `SendGameRequest`, + - `SendMediaGroupRequest` + ## [v20.0.0] - Unreleased From a3bcf7f7c71973a54e2701cd45c283353f97ad31 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 20:59:52 +0300 Subject: [PATCH 09/90] SendLocation: missing property HorizontalAccuracy --- .../Messages/Location/SendLocationRequest.cs | 6 ++++++ src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs | 3 +++ 2 files changed, 9 insertions(+) diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs index b33a21e97..a8deb3ac6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs @@ -32,6 +32,12 @@ public class SendLocationRequest : RequestBase, IChatTargetable [JsonProperty(Required = Required.Always)] public double Longitude { get; } + /// + /// The radius of uncertainty for the location, measured in meters; 0-1500 + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public double? HorizontalAccuracy { get; set; } + /// /// Period in seconds for which the location will be updated, should be between 60 and 86400 /// diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 8f2c68ab0..770a2c9a5 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -1137,6 +1137,7 @@ await botClient.ThrowIfNull() /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only /// + /// The radius of uncertainty for the location, measured in meters; 0-1500 /// /// Period in seconds for which the location will be updated, should be between 60 and 86400 /// @@ -1169,6 +1170,7 @@ public static async Task SendLocationAsync( double latitude, double longitude, int? messageThreadId = default, + double? horizontalAccuracy = default, int? livePeriod = default, int? heading = default, int? proximityAlertRadius = default, @@ -1183,6 +1185,7 @@ await botClient.ThrowIfNull() request: new SendLocationRequest(chatId, latitude, longitude) { MessageThreadId = messageThreadId, + HorizontalAccuracy = horizontalAccuracy, LivePeriod = livePeriod, Heading = heading, ProximityAlertRadius = proximityAlertRadius, From f40c7b30e79fd9629be0e1c564e2c847bf8040dc Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:07:54 +0300 Subject: [PATCH 10/90] Reactions: address feedback --- src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs | 2 +- src/Telegram.Bot/Types/ReactionType.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 770a2c9a5..760d96ec9 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -1762,7 +1762,7 @@ public static async Task SetMessageReactionAsync( this ITelegramBotClient botClient, ChatId chatId, int messageId, - ReactionType[]? reaction, + IEnumerable? reaction, bool? isBig, CancellationToken cancellationToken = default ) => diff --git a/src/Telegram.Bot/Types/ReactionType.cs b/src/Telegram.Bot/Types/ReactionType.cs index 3e1afee65..571c15c0d 100644 --- a/src/Telegram.Bot/Types/ReactionType.cs +++ b/src/Telegram.Bot/Types/ReactionType.cs @@ -5,8 +5,8 @@ namespace Telegram.Bot.Types; /// /// This object describes the type of a reaction. Currently, it can be one of /// -/// ReactionTypeEmoji -/// ReactionTypeCustomEmoji +/// +/// /// /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] From 6d8ed08aefecd724cbcc309a8a4f5ca27e7fa82d Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:34:07 +0300 Subject: [PATCH 11/90] Link Preview Customization --- .../Messages/SendMessageRequest.cs | 4 +- .../EditInlineMessageTextRequest.cs | 4 +- .../EditMessageTextRequest.cs | 4 +- .../TelegramBotClientExtensions.ApiMethods.cs | 19 ++++----- .../InputTextMessageContent.cs | 4 +- src/Telegram.Bot/Types/LinkPreviewOptions.cs | 42 +++++++++++++++++++ src/Telegram.Bot/Types/Message.cs | 7 ++++ 7 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 src/Telegram.Bot/Types/LinkPreviewOptions.cs diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs index f330759a0..cc2c15c49 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs @@ -37,10 +37,10 @@ public class SendMessageRequest : RequestBase, IChatTargetable public IEnumerable? Entities { get; set; } /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? DisableWebPagePreview { get; set; } + public LinkPreviewOptions? LinkPreviewOptions { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs index a44308bb4..87770203b 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs @@ -31,10 +31,10 @@ public class EditInlineMessageTextRequest : RequestBase public IEnumerable? Entities { get; set; } /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? DisableWebPagePreview { get; set; } + public LinkPreviewOptions? LinkPreviewOptions { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs index b3bbba159..2670697af 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs @@ -37,10 +37,10 @@ public class EditMessageTextRequest : RequestBase, IChatTargetable public IEnumerable? Entities { get; set; } /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? DisableWebPagePreview { get; set; } + public LinkPreviewOptions? LinkPreviewOptions { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 760d96ec9..968213496 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -293,7 +293,7 @@ await botClient.ThrowIfNull() /// List of special entities that appear in message text, which can be specified instead /// of /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// /// Sends the message silently. Users will receive a notification with no sound /// @@ -316,7 +316,7 @@ public static async Task SendTextMessageAsync( int? messageThreadId = default, ParseMode? parseMode = default, IEnumerable? entities = default, - bool? disableWebPagePreview = default, + LinkPreviewOptions? linkPreviewOptions = default, bool? disableNotification = default, bool? protectContent = default, ReplyParameters? replyParameters = default, @@ -330,12 +330,11 @@ await botClient.ThrowIfNull() MessageThreadId = messageThreadId, ParseMode = parseMode, Entities = entities, - DisableWebPagePreview = disableWebPagePreview, + LinkPreviewOptions = linkPreviewOptions, DisableNotification = disableNotification, ProtectContent = protectContent, ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, - MessageThreadId = messageThreadId, }, cancellationToken ) @@ -3548,7 +3547,7 @@ await botClient.ThrowIfNull() /// List of special entities that appear in message text, which can be specified instead /// of /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -3566,7 +3565,7 @@ public static async Task EditMessageTextAsync( string text, ParseMode? parseMode = default, IEnumerable? entities = default, - bool? disableWebPagePreview = default, + LinkPreviewOptions? linkPreviewOptions = default, InlineKeyboardMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -3576,7 +3575,7 @@ await botClient.ThrowIfNull() { ParseMode = parseMode, Entities = entities, - DisableWebPagePreview = disableWebPagePreview, + LinkPreviewOptions = linkPreviewOptions, ReplyMarkup = replyMarkup }, cancellationToken @@ -3598,7 +3597,7 @@ await botClient.ThrowIfNull() /// List of special entities that appear in message text, which can be specified instead /// of /// - /// Disables link previews for links in this message + /// Link preview generation options for the message /// /// Additional interface options. An inline keyboard, /// custom reply keyboard, instructions to @@ -3614,7 +3613,7 @@ public static async Task EditMessageTextAsync( string text, ParseMode? parseMode = default, IEnumerable? entities = default, - bool? disableWebPagePreview = default, + LinkPreviewOptions? linkPreviewOptions = default, InlineKeyboardMarkup? replyMarkup = default, CancellationToken cancellationToken = default ) => @@ -3624,7 +3623,7 @@ await botClient.ThrowIfNull() { ParseMode = parseMode, Entities = entities, - DisableWebPagePreview = disableWebPagePreview, + LinkPreviewOptions = linkPreviewOptions, ReplyMarkup = replyMarkup }, cancellationToken diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs index 0cba239fd..5e521492e 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs @@ -32,10 +32,10 @@ public class InputTextMessageContent : InputMessageContent public MessageEntity[]? Entities { get; set; } // ToDo: add test /// - /// Optional. Disables link previews for links in the sent message + /// Optional. Link preview generation options for the message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? DisableWebPagePreview { get; set; } + public LinkPreviewOptions? LinkPreviewOptions { get; set; } /// /// Initializes a new input text message content diff --git a/src/Telegram.Bot/Types/LinkPreviewOptions.cs b/src/Telegram.Bot/Types/LinkPreviewOptions.cs new file mode 100644 index 000000000..565ff812a --- /dev/null +++ b/src/Telegram.Bot/Types/LinkPreviewOptions.cs @@ -0,0 +1,42 @@ +namespace Telegram.Bot.Types; + +/// +/// Describes the options used for link preview generation. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class LinkPreviewOptions +{ + /// + /// Optional. , if the link preview is disabled + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? IsDisabled { get; set; } + + /// + /// Optional. URL to use for the link preview. If empty, then the first URL found in the message text + /// will be used + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? Url { get; set; } + + /// + /// Optional. , if the media in the link preview is supposed to be shrunk; + /// ignored if the URL isn't explicitly specified or media size change isn't supported for the preview + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? PreferSmallMedia { get; set; } + + /// + /// Optional. , if the media in the link preview is supposed to be enlarged; + /// ignored if the URL isn't explicitly specified or media size change isn't supported for the preview + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? PreferLargeMedia { get; set; } + + /// + /// Optional. , if the link preview must be shown above the message text; + /// otherwise, the link preview will be shown below the message text + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? ShowAboveText { get; set; } +} diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index a7cbd4fbb..f7900c21e 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -149,6 +149,13 @@ Text is null ? default : Entities?.Select(entity => Text.Substring(entity.Offset, entity.Length)); + /// + /// Optional. Options used for link preview generation for the message, if it is a text message + /// and link preview options were changed + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public LinkPreviewOptions? LinkPreviewOptions { get; set; } + /// /// Optional. Message is an animation, information about the animation. For backward compatibility, when this /// field is set, the field will also be set From 154a3335ad546d9f0349854919eb5db0ab66fd32 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:34:37 +0300 Subject: [PATCH 12/90] Reactions: address feedback --- .../Available methods/Messages/SetMessageReactionRequest.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs index f31822e4f..3c01fb424 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs @@ -1,6 +1,7 @@ -// ReSharper disable once CheckNamespace +using System.Collections.Generic; using Telegram.Bot.Requests.Abstractions; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -30,7 +31,7 @@ public class SetMessageReactionRequest : RequestBase, /// already present on the message or explicitly allowed by chat administrators. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public ReactionType[]? Reaction { get; set; } + public IEnumerable? Reaction { get; set; } /// /// Pass to set the reaction with a big animation From 4cbb871c6a232b3bc2d0cb596939737307e3d654 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:44:35 +0300 Subject: [PATCH 13/90] Link Preview Customization: update CHANGELOG --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1401713b7..5a70d7856 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,12 +36,14 @@ and the property `MessageReactionCount` in the class `Update`. The bot must expl - Type `ReactionCount`. - Request type `SetMessageReactionRequest` that allows bots to react to messages. - New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages. -- The field `AvailableReactions` to the class `Chat`. +- The property `AvailableReactions` to the class `Chat`. - The class `ExternalReplyInfo` and the property `ExternalReply` of type `ExternalReplyInfo` to the class `Message`, containing information about a message that is replied to by the current message, but can be from another chat or forum topic. - Added the class `TextQuote` and the property `Quote` of type `TextQuote` to the class `Message`, which contains the part of the replied message text or caption that is quoted in the current message. - The class `ReplyParameters`. +- The class `LinkPreviewOptions`. +- The property `LinkPreviewOptions` to the class `Message` with information about the link preview options used to send the message. ### Changed @@ -83,6 +85,10 @@ which contains the part of the replied message text or caption that is quoted in - `SendInvoiceRequest`, - `SendGameRequest`, - `SendMediaGroupRequest` +- Replaced the parameter `DisableWebPagePreview` with `LinkPreviewOptions` in the methods `SendTextMessageAsync` and `EditMessageTextAsync`. +- Replaced the property `DisableWebPagePreview` with `LinkPreviewOptions` in the request classes `SendMessageRequest`, `EditMessageTextRequest` + and `EditInlineMessageTextRequest`. + - Replaced the property disable_web_page_preview with `DisableWebPagePreview` in the class `InputTextMessageContent`. ## [v20.0.0] - Unreleased From f0bc8a7263f474075c63a3c5994c66a3c1b3b453 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 21:57:40 +0300 Subject: [PATCH 14/90] Block Quotation --- CHANGELOG.md | 1 + src/Telegram.Bot/Types/Enums/MessageEntityType.cs | 5 +++++ .../EnumConverter/MessageEntityTypeConverterTests.cs | 1 + 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a70d7856..4acf07df6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ which contains the part of the replied message text or caption that is quoted in - The class `ReplyParameters`. - The class `LinkPreviewOptions`. - The property `LinkPreviewOptions` to the class `Message` with information about the link preview options used to send the message. +- New enum value `Blockquote` for `MessageEntityType`. ### Changed diff --git a/src/Telegram.Bot/Types/Enums/MessageEntityType.cs b/src/Telegram.Bot/Types/Enums/MessageEntityType.cs index b372293ba..891e44695 100644 --- a/src/Telegram.Bot/Types/Enums/MessageEntityType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageEntityType.cs @@ -90,4 +90,9 @@ public enum MessageEntityType /// Inline custom emoji stickers /// CustomEmoji, + + /// + /// Block quotation + /// + Blockquote, } diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageEntityTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageEntityTypeConverterTests.cs index dbedfca50..664c7dbc6 100644 --- a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageEntityTypeConverterTests.cs +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageEntityTypeConverterTests.cs @@ -97,6 +97,7 @@ public IEnumerator GetEnumerator() yield return new object[] { MessageEntityType.Strikethrough, "strikethrough" }; yield return new object[] { MessageEntityType.Spoiler, "spoiler" }; yield return new object[] { MessageEntityType.CustomEmoji, "custom_emoji" }; + yield return new object[] { MessageEntityType.Blockquote, "blockquote" }; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); From e662a4f811b4a80f585fd9366b7ec794040e2cfc Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 3 Jan 2024 22:44:44 +0300 Subject: [PATCH 15/90] Multiple Message Actions --- CHANGELOG.md | 4 +- .../Messages/CopyMessagesRequest.cs | 80 ++++++++++ .../Messages/ForwardMessagesRequest.cs | 73 +++++++++ .../DeleteMessagesRequest.cs | 43 ++++++ .../TelegramBotClientExtensions.ApiMethods.cs | 140 ++++++++++++++++++ 5 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs create mode 100644 src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs create mode 100644 src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4acf07df6..f1eefb115 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,7 +34,7 @@ and the property `MessageReaction` in the class `Update`. The bot must explicitl and the property `MessageReactionCount` in the class `Update`. The bot must explicitly allow the update to receive it. - New enum values `MessageReaction`, `MessageReactionCount` for `UpdateType`. - Type `ReactionCount`. -- Request type `SetMessageReactionRequest` that allows bots to react to messages. +- Request classes `SetMessageReactionRequest` that allows bots to react to messages. - New method `ITelegramBotClient.SetMessageReactionAsync` that allows bots to react to messages. - The property `AvailableReactions` to the class `Chat`. - The class `ExternalReplyInfo` and the property `ExternalReply` of type `ExternalReplyInfo` to the class `Message`, @@ -45,6 +45,8 @@ which contains the part of the replied message text or caption that is quoted in - The class `LinkPreviewOptions`. - The property `LinkPreviewOptions` to the class `Message` with information about the link preview options used to send the message. - New enum value `Blockquote` for `MessageEntityType`. +- Request classes `DeleteMessagesRequest`, `ForwardMessagesRequest` and `CopyMessagesRequest`. +- New methods `ITelegramBotClient.DeleteMessagesAsync`, `ITelegramBotClient.ForwardMessagesAsync` and `ITelegramBotClient.CopyMessagesAsync`. ### Changed diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs new file mode 100644 index 000000000..180763fe3 --- /dev/null +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs @@ -0,0 +1,80 @@ +using Telegram.Bot.Requests.Abstractions; + +// ReSharper disable once CheckNamespace +namespace Telegram.Bot.Requests; + +/// +/// Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, +/// they are skipped. Service messages, giveaway messages, giveaway winners messages, and invoice messages +/// can't be copied. A quiz can be copied only if the value of the field +/// CorrectOptionId is known to the bot. The method is analogous +/// to the method , but the copied messages don't have a link +/// to the original message. Album grouping is kept for copied messages. +/// On success, an array of of the sent messages is returned. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class CopyMessagesRequest : RequestBase, IChatTargetable +{ + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + [JsonProperty(Required = Required.Always)] + public ChatId ChatId { get; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } + + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + [JsonProperty(Required = Required.Always)] + public ChatId FromChatId { get; } + + /// + /// Identifiers of 1-100 messages in the chat to copy. + /// The identifiers must be specified in a strictly increasing order. + /// + [JsonProperty(Required = Required.Always)] + public int[] MessageIds { get; } + + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? DisableNotification { get; set; } + + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? ProtectContent { get; set; } + + /// + /// Pass to copy the messages without their captions + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? RemoveCaption { get; set; } + + /// + /// Initializes a new request with chatId, fromChatId and messageIds + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages in the chat to copy. + /// The identifiers must be specified in a strictly increasing order. + /// + public CopyMessagesRequest(ChatId chatId, ChatId fromChatId, int[] messageIds) + : base("copyMessages") + { + ChatId = chatId; + FromChatId = fromChatId; + MessageIds = messageIds; + } +} diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs new file mode 100644 index 000000000..d22dbbb3d --- /dev/null +++ b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs @@ -0,0 +1,73 @@ +using System.Collections.Generic; +using Telegram.Bot.Requests.Abstractions; + +// ReSharper disable once CheckNamespace +namespace Telegram.Bot.Requests; + +/// +/// Use this method to forward multiple messages of any kind. If some of the specified messages can't be found +/// or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. +/// Album grouping is kept for forwarded messages. +/// On success, an array of of the sent messages is returned. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ForwardMessagesRequest : RequestBase, IChatTargetable +{ + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + [JsonProperty(Required = Required.Always)] + public ChatId ChatId { get; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } + + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + [JsonProperty(Required = Required.Always)] + public ChatId FromChatId { get; } + + /// + /// Identifiers of 1-100 messages in the chat from_chat_id to forward. + /// The identifiers must be specified in a strictly increasing order. + /// + [JsonProperty(Required = Required.Always)] + public IEnumerable MessageIds { get; } + + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? DisableNotification { get; set; } + + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? ProtectContent { get; set; } + + /// + /// Initializes a new request with chatId, fromChatId and messageIds + /// + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages in the chat from_chat_id to forward. + /// The identifiers must be specified in a strictly increasing order. + /// + public ForwardMessagesRequest(ChatId chatId, ChatId fromChatId, IEnumerable messageIds) + :base("forwardMessages") + { + ChatId = chatId; + FromChatId = fromChatId; + MessageIds = messageIds; + } +} diff --git a/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs new file mode 100644 index 000000000..44ed5526b --- /dev/null +++ b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using Telegram.Bot.Requests.Abstractions; + +// ReSharper disable once CheckNamespace +namespace Telegram.Bot.Requests; + +/// +/// Use this method to delete multiple messages simultaneously. +/// If some of the specified messages can't be found, they are skipped. +/// Returns on success. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class DeleteMessagesRequest : RequestBase, IChatTargetable +{ + /// + [JsonProperty(Required = Required.Always)] + public ChatId ChatId { get; } + + /// + /// Identifiers of 1-100 messages to delete. See + /// for limitations on which messages can be deleted + /// + [JsonProperty(Required = Required.Always)] + public IEnumerable MessageIds { get; } + + /// + /// Initializes a new request with chatId and messageIds + /// + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages to delete. See + /// for limitations on which messages can be deleted + /// + public DeleteMessagesRequest(ChatId chatId, IEnumerable messageIds) + :base("deleteMessages") + { + ChatId = chatId; + MessageIds = messageIds; + } +} diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 968213496..b456fe9f0 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -378,9 +378,62 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new ForwardMessageRequest(chatId, fromChatId, messageId) { + MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, + }, + cancellationToken + ) + .ConfigureAwait(false); + + /// + /// Use this method to forward multiple messages of any kind. If some of the specified messages can't be found + /// or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. + /// Album grouping is kept for forwarded messages. + /// + /// An instance of + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages in the chat from_chat_id to forward. + /// The identifiers must be specified in a strictly increasing order. + /// + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + /// + /// Sends the message silently. Users will receive a notification with no sound. + /// + /// + /// Protects the contents of sent messages from forwarding and saving + /// + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, an array of of the sent messages is returned. + public static async Task ForwardMessagesAsync( + this ITelegramBotClient botClient, + ChatId chatId, + ChatId fromChatId, + IEnumerable messageIds, + int? messageThreadId = default, + bool? disableNotification = default, + bool? protectContent = default, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync( + request: new ForwardMessagesRequest(chatId, fromChatId, messageIds) + { MessageThreadId = messageThreadId, + DisableNotification = disableNotification, + ProtectContent = protectContent, }, cancellationToken ) @@ -451,6 +504,7 @@ await botClient.ThrowIfNull() .MakeRequestAsync( request: new CopyMessageRequest(chatId, fromChatId, messageId) { + MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, @@ -458,7 +512,67 @@ await botClient.ThrowIfNull() ProtectContent = protectContent, ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, + }, + cancellationToken + ) + .ConfigureAwait(false); + + /// + /// Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, + /// they are skipped. Service messages, giveaway messages, giveaway winners messages, and invoice messages + /// can't be copied. A quiz can be copied only if the value of the field + /// CorrectOptionId is known to the bot. The method is analogous + /// to the method , but the copied messages don't have a link + /// to the original message. Album grouping is kept for copied messages. + /// + /// An instance of + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Unique identifier for the chat where the original messages were sent + /// (or channel username in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages in the chat to copy. + /// The identifiers must be specified in a strictly increasing order. + /// + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + /// + /// Sends the message silently. Users will receive a notification with no sound. + /// + /// + /// Protects the contents of sent messages from forwarding and saving + /// + /// + /// Pass to copy the messages without their captions + /// + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, an array of of the sent messages is returned. + public static async Task CopyMessagesAsync( + this ITelegramBotClient botClient, + ChatId chatId, + ChatId fromChatId, + int[] messageIds, + int? messageThreadId = default, + bool? disableNotification = default, + bool? protectContent = default, + bool? RemoveCaption = default, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync( + request: new CopyMessagesRequest(chatId, fromChatId, messageIds) + { MessageThreadId = messageThreadId, + DisableNotification = disableNotification, + ProtectContent = protectContent, + RemoveCaption = RemoveCaption, }, cancellationToken ) @@ -3939,6 +4053,32 @@ await botClient.ThrowIfNull() .MakeRequestAsync(request: new DeleteMessageRequest(chatId, messageId), cancellationToken) .ConfigureAwait(false); + /// + /// Use this method to delete multiple messages simultaneously. + /// If some of the specified messages can't be found, they are skipped. + /// + /// An instance of + /// + /// Unique identifier for the target chat or username of the target channel + /// (in the format @channelusername) + /// + /// + /// Identifiers of 1-100 messages to delete. See + /// for limitations on which messages can be deleted + /// + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteMessagesAsync( + this ITelegramBotClient botClient, + ChatId chatId, + IEnumerable messageIds, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request: new DeleteMessagesRequest(chatId, messageIds), cancellationToken) + .ConfigureAwait(false); + #endregion Updating messages #region Stickers From d214dafa02951589875122e5608e6ce4a8efd91c Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 00:05:35 +0300 Subject: [PATCH 16/90] Request for multiple users --- CHANGELOG.md | 8 +- src/Telegram.Bot/Types/Enums/MessageType.cs | 4 +- src/Telegram.Bot/Types/Message.cs | 2 +- .../Types/ReplyMarkups/KeyboardButton.cs | 32 +--- .../ReplyMarkups/KeyboardButtonRequestUser.cs | 29 --- .../KeyboardButtonRequestUsers.cs | 36 ++++ src/Telegram.Bot/Types/UserShared.cs | 27 --- src/Telegram.Bot/Types/UsersShared.cs | 27 +++ .../MessageTypeConverterTests.cs | 177 ++++++++++-------- 9 files changed, 178 insertions(+), 164 deletions(-) delete mode 100644 src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUser.cs create mode 100644 src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs delete mode 100644 src/Telegram.Bot/Types/UserShared.cs create mode 100644 src/Telegram.Bot/Types/UsersShared.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index f1eefb115..b7d9a3778 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,8 +91,12 @@ which contains the part of the replied message text or caption that is quoted in - Replaced the parameter `DisableWebPagePreview` with `LinkPreviewOptions` in the methods `SendTextMessageAsync` and `EditMessageTextAsync`. - Replaced the property `DisableWebPagePreview` with `LinkPreviewOptions` in the request classes `SendMessageRequest`, `EditMessageTextRequest` and `EditInlineMessageTextRequest`. - - Replaced the property disable_web_page_preview with `DisableWebPagePreview` in the class `InputTextMessageContent`. - +- Replaced the property disable_web_page_preview with `DisableWebPagePreview` in the class `InputTextMessageContent`. +- Renamed the class `KeyboardButtonRequestUser` to `KeyboardButtonRequestUsers` and added the property `MaxQuantity` to it. +- Renamed the property `RequestUser` in the class `KeyboardButton` to `RequestUsers`. The old name will still work for backward compatibility. +- Renamed the class `UserShared` to `UsersShared` and changed the property `UserId` to `UserIds`. +- Replaced the property `UserShared` in the class Message with the property `UsersShared`. +- Replaced enum member `MessageType.UserShared` with `MessageType.UsersShared` ## [v20.0.0] - Unreleased diff --git a/src/Telegram.Bot/Types/Enums/MessageType.cs b/src/Telegram.Bot/Types/Enums/MessageType.cs index 97ddbc946..7c1109502 100644 --- a/src/Telegram.Bot/Types/Enums/MessageType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageType.cs @@ -227,9 +227,9 @@ public enum MessageType WriteAccessAllowed, /// - /// The contains + /// The contains a /// - UserShared, + UsersShared, /// /// The contains diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index f7900c21e..e1259a4ea 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -374,7 +374,7 @@ Caption is null /// Optional. Service message: a user was shared with the bot /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public UserShared? UserShared { get; set; } + public UsersShared? UsersShared { get; set; } /// /// Optional. Service message: a chat was shared with the bot diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs index 3266255ae..5c3f7957c 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs @@ -1,23 +1,11 @@ namespace Telegram.Bot.Types.ReplyMarkups; /// -/// This object represents one button of the reply keyboard. For simple text buttons can be -/// used instead of this object to specify text of the button. +/// This object represents one button of the reply keyboard. +/// For simple text buttons, can be used instead of this object to specify the button text. +/// The optional fields , , , +/// , , and are mutually exclusive. /// -/// -/// -/// Note: and options will only work in Telegram -/// versions released after 9 April, 2016. Older clients will display unsupported message. -/// -/// -/// Note: option will only work in Telegram versions released after 23 January, 2020. -/// Older clients will display unsupported message. -/// -/// -/// Note: option will only work in Telegram versions released after 16 April, 2022. Older -/// clients will display unsupported message. -/// -/// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class KeyboardButton : IKeyboardButton { @@ -26,11 +14,11 @@ public class KeyboardButton : IKeyboardButton public string Text { get; set; } /// - /// Optional. If specified, pressing the button will open a list of suitable users. Tapping on any user will send - /// their identifier to the bot in a “user_shared” service message. Available in private chats only. + /// Optional. If specified, pressing the button will open a list of suitable users. Identifiers of selected users + /// will be sent to the bot in a "" service message. Available in private chats only. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public KeyboardButtonRequestUser? RequestUser { get; set; } + public KeyboardButtonRequestUsers? RequestUsers { get; set; } /// /// Optional. If specified, pressing the button will open a list of suitable chats. Tapping on a chat will send @@ -112,10 +100,10 @@ public static KeyboardButton WithWebApp(string text, WebAppInfo webAppInfo) => /// Generate a keyboard button to request user info /// /// Button's text - /// Criteria used to request a suitable user + /// Criteria used to request a suitable users /// - public static KeyboardButton WithRequestUser(string text, KeyboardButtonRequestUser requestUser) => - new(text) { RequestUser = requestUser }; + public static KeyboardButton WithRequestUser(string text, KeyboardButtonRequestUsers requestUsers) => + new(text) { RequestUsers = requestUsers }; /// /// Generate a keyboard button to request chat info diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUser.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUser.cs deleted file mode 100644 index 00d4552aa..000000000 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUser.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Telegram.Bot.Types.ReplyMarkups; - -/// -/// This object defines the criteria used to request a suitable user. The identifier of the selected user will be -/// shared with the bot when the corresponding button is pressed. -/// -[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class KeyboardButtonRequestUser -{ - /// - /// Signed 32-bit identifier of the request - /// - [JsonProperty(Required = Required.Always)] - public int RequestId { get; set; } - - /// - /// Optional. Pass to request a bot, pass to request a regular user. If not specified, no additional - /// restrictions are applied. - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? UserIsBot { get; set; } - - /// - /// Optional. Pass to request a premium user, pass to request a non-premium user. If not specified, - /// no additional restrictions are applied. - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public bool? UserIsPremium { get; set; } -} diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs new file mode 100644 index 000000000..9629516d9 --- /dev/null +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs @@ -0,0 +1,36 @@ +namespace Telegram.Bot.Types.ReplyMarkups; + +/// +/// This object defines the criteria used to request a suitable user. The identifier of the selected user will be +/// shared with the bot when the corresponding button is pressed. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class KeyboardButtonRequestUsers +{ + /// + /// Signed 32-bit identifier of the request that will be received back in the object. + /// Must be unique within the message + /// + [JsonProperty(Required = Required.Always)] + public int RequestId { get; set; } + + /// + /// Optional. Pass to request bots, pass to request regular users. + /// If not specified, no additional restrictions are applied. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? UserIsBot { get; set; } + + /// + /// Optional. Pass to request premium users, pass to request non-premium users. + /// If not specified, no additional restrictions are applied. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? UserIsPremium { get; set; } + + /// + /// Optional. The maximum number of users to be selected; 1-10. Defaults to 1. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MaxQuantity { get; set; } +} diff --git a/src/Telegram.Bot/Types/UserShared.cs b/src/Telegram.Bot/Types/UserShared.cs deleted file mode 100644 index 885634920..000000000 --- a/src/Telegram.Bot/Types/UserShared.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Telegram.Bot.Types.ReplyMarkups; - -namespace Telegram.Bot.Types; - -/// -/// This object contains information about the user whose identifier was shared with the bot using a -/// button. -/// -[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class UserShared -{ - /// - /// Identifier of the request - /// - [JsonProperty(Required = Required.Always)] - public int RequestId { get; set; } - - /// - /// Identifier of the shared user. This number may have more than 32 significant bits and some programming - /// languages may have difficulty/silent defects in interpreting it. But it has at most 52 significant bits, - /// so a 64-bit integer or double-precision float type are safe for storing this identifier. The bot may not have - /// access to the user and could be unable to use this identifier, unless the user is already known to the bot by - /// some other means. - /// - [JsonProperty(Required = Required.Always)] - public long UserId { get; set; } -} diff --git a/src/Telegram.Bot/Types/UsersShared.cs b/src/Telegram.Bot/Types/UsersShared.cs new file mode 100644 index 000000000..de9414fcc --- /dev/null +++ b/src/Telegram.Bot/Types/UsersShared.cs @@ -0,0 +1,27 @@ +using Telegram.Bot.Types.ReplyMarkups; + +namespace Telegram.Bot.Types; + +/// +/// This object contains information about the users whose identifiers were shared with the bot +/// using a button. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class UsersShared +{ + /// + /// Identifier of the request + /// + [JsonProperty(Required = Required.Always)] + public int RequestId { get; set; } + + /// + /// Identifiers of the shared users. These numbers may have more than 32 significant bits and some + /// programming languages may have difficulty/silent defects in interpreting them. But they have + /// at most 52 significant bits, so 64-bit integers or double-precision float types are safe for + /// storing these identifiers. The bot may not have access to the users and could be unable to use + /// these identifiers, unless the users are already known to the bot by some other means. + /// + [JsonProperty(Required = Required.Always)] + public long[] UserIds { get; set; } = Array.Empty(); +} diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs index 65696ca78..dd4019c34 100644 --- a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs @@ -1,4 +1,7 @@ using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using Telegram.Bot.Types.Enums; @@ -8,47 +11,31 @@ namespace Telegram.Bot.Tests.Unit.EnumConverter; public class MessageTypeConverterTests { + [Fact] + public void Should_Verify_All_MessageType_Members() + { + List messageTypeMembers = Enum + .GetNames() + .OrderBy(x => x) + .ToList(); + List messageTypeDataMembers = new MessageTypeData() + .Select(x => Enum.GetName(typeof(MessageType), x[0])) + .OrderBy(x => x) + .ToList()!; + + Assert.Equal(messageTypeMembers.Count, messageTypeDataMembers.Count); + Assert.Equal(messageTypeMembers, messageTypeDataMembers); + } + [Theory] - [InlineData(MessageType.Unknown, "unknown")] - [InlineData(MessageType.Text, "text")] - [InlineData(MessageType.Photo, "photo")] - [InlineData(MessageType.Audio, "audio")] - [InlineData(MessageType.Video, "video")] - [InlineData(MessageType.Voice, "voice")] - [InlineData(MessageType.Animation, "animation")] - [InlineData(MessageType.Document, "document")] - [InlineData(MessageType.Sticker, "sticker")] - [InlineData(MessageType.Location, "location")] - [InlineData(MessageType.Contact, "contact")] - [InlineData(MessageType.Venue, "venue")] - [InlineData(MessageType.Game, "game")] - [InlineData(MessageType.VideoNote, "video_note")] - [InlineData(MessageType.Invoice, "invoice")] - [InlineData(MessageType.SuccessfulPayment, "successful_payment")] - [InlineData(MessageType.WebsiteConnected, "website_connected")] - [InlineData(MessageType.ChatMembersAdded, "chat_members_added")] - [InlineData(MessageType.ChatMemberLeft, "chat_member_left")] - [InlineData(MessageType.ChatTitleChanged, "chat_title_changed")] - [InlineData(MessageType.ChatPhotoChanged, "chat_photo_changed")] - [InlineData(MessageType.MessagePinned, "message_pinned")] - [InlineData(MessageType.ChatPhotoDeleted, "chat_photo_deleted")] - [InlineData(MessageType.GroupCreated, "group_created")] - [InlineData(MessageType.SupergroupCreated, "supergroup_created")] - [InlineData(MessageType.ChannelCreated, "channel_created")] - [InlineData(MessageType.MigratedToSupergroup, "migrated_to_supergroup")] - [InlineData(MessageType.MigratedFromGroup, "migrated_from_group")] - [InlineData(MessageType.Poll, "poll")] - [InlineData(MessageType.Dice, "dice")] - [InlineData(MessageType.MessageAutoDeleteTimerChanged, "message_auto_delete_timer_changed")] - [InlineData(MessageType.ProximityAlertTriggered, "proximity_alert_triggered")] - [InlineData(MessageType.VideoChatScheduled, "video_chat_scheduled")] - [InlineData(MessageType.VideoChatStarted, "video_chat_started")] - [InlineData(MessageType.VideoChatEnded, "video_chat_ended")] - [InlineData(MessageType.VideoChatParticipantsInvited, "video_chat_participants_invited")] + [ClassData(typeof(MessageTypeData))] public void Should_Convert_UpdateType_To_String(MessageType messageType, string value) { - Message message = new() { Type = messageType }; - string expectedResult = @$"{{""type"":""{value}""}}"; + Message message = new(messageType); + string expectedResult = + $$""" + {"type":"{{value}}"} + """; string result = JsonConvert.SerializeObject(message); @@ -56,46 +43,14 @@ public void Should_Convert_UpdateType_To_String(MessageType messageType, string } [Theory] - [InlineData(MessageType.Unknown, "unknown")] - [InlineData(MessageType.Text, "text")] - [InlineData(MessageType.Photo, "photo")] - [InlineData(MessageType.Audio, "audio")] - [InlineData(MessageType.Video, "video")] - [InlineData(MessageType.Voice, "voice")] - [InlineData(MessageType.Animation, "animation")] - [InlineData(MessageType.Document, "document")] - [InlineData(MessageType.Sticker, "sticker")] - [InlineData(MessageType.Location, "location")] - [InlineData(MessageType.Contact, "contact")] - [InlineData(MessageType.Venue, "venue")] - [InlineData(MessageType.Game, "game")] - [InlineData(MessageType.VideoNote, "video_note")] - [InlineData(MessageType.Invoice, "invoice")] - [InlineData(MessageType.SuccessfulPayment, "successful_payment")] - [InlineData(MessageType.WebsiteConnected, "website_connected")] - [InlineData(MessageType.ChatMembersAdded, "chat_members_added")] - [InlineData(MessageType.ChatMemberLeft, "chat_member_left")] - [InlineData(MessageType.ChatTitleChanged, "chat_title_changed")] - [InlineData(MessageType.ChatPhotoChanged, "chat_photo_changed")] - [InlineData(MessageType.MessagePinned, "message_pinned")] - [InlineData(MessageType.ChatPhotoDeleted, "chat_photo_deleted")] - [InlineData(MessageType.GroupCreated, "group_created")] - [InlineData(MessageType.SupergroupCreated, "supergroup_created")] - [InlineData(MessageType.ChannelCreated, "channel_created")] - [InlineData(MessageType.MigratedToSupergroup, "migrated_to_supergroup")] - [InlineData(MessageType.MigratedFromGroup, "migrated_from_group")] - [InlineData(MessageType.Poll, "poll")] - [InlineData(MessageType.Dice, "dice")] - [InlineData(MessageType.MessageAutoDeleteTimerChanged, "message_auto_delete_timer_changed")] - [InlineData(MessageType.ProximityAlertTriggered, "proximity_alert_triggered")] - [InlineData(MessageType.VideoChatScheduled, "video_chat_scheduled")] - [InlineData(MessageType.VideoChatStarted, "video_chat_started")] - [InlineData(MessageType.VideoChatEnded, "video_chat_ended")] - [InlineData(MessageType.VideoChatParticipantsInvited, "video_chat_participants_invited")] + [ClassData(typeof(MessageTypeData))] public void Should_Convert_String_To_UpdateType(MessageType messageType, string value) { - Message expectedResult = new() { Type = messageType }; - string jsonData = @$"{{""type"":""{value}""}}"; + Message expectedResult = new(messageType); + string jsonData = + $$""" + {"type":"{{value}}"} + """; Message? result = JsonConvert.DeserializeObject(jsonData); @@ -106,7 +61,10 @@ public void Should_Convert_String_To_UpdateType(MessageType messageType, string [Fact] public void Should_Return_Unknown_For_Incorrect_UpdateType() { - string jsonData = @$"{{""type"":""{int.MaxValue}""}}"; + string jsonData = + $$""" + {"type":"{{int.MaxValue}}"} + """; Message? result = JsonConvert.DeserializeObject(jsonData); @@ -117,15 +75,72 @@ public void Should_Return_Unknown_For_Incorrect_UpdateType() [Fact] public void Should_Throw_NotSupportedException_For_Incorrect_MessageType() { - Message message = new() { Type = (MessageType)int.MaxValue }; + Message message = new((MessageType)int.MaxValue ); Assert.Throws(() => JsonConvert.SerializeObject(message)); } [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] - class Message + record Message([property: JsonProperty(Required = Required.Always)] MessageType Type); + + private class MessageTypeData : IEnumerable { - [JsonProperty(Required = Required.Always)] - public MessageType Type { get; init; } + public IEnumerator GetEnumerator() + { + yield return new object[] { MessageType.Unknown, "unknown" }; + yield return new object[] { MessageType.Text, "text" }; + yield return new object[] { MessageType.Animation, "animation" }; + yield return new object[] { MessageType.Audio, "audio" }; + yield return new object[] { MessageType.Document, "document" }; + yield return new object[] { MessageType.Photo, "photo" }; + yield return new object[] { MessageType.Sticker, "sticker" }; + yield return new object[] { MessageType.Story, "story" }; + yield return new object[] { MessageType.Video, "video" }; + yield return new object[] { MessageType.VideoNote, "video_note" }; + yield return new object[] { MessageType.Voice, "voice" }; + yield return new object[] { MessageType.Contact, "contact" }; + yield return new object[] { MessageType.Dice, "dice" }; + yield return new object[] { MessageType.Game, "game" }; + yield return new object[] { MessageType.Poll, "poll" }; + yield return new object[] { MessageType.Venue, "venue" }; + yield return new object[] { MessageType.Location, "location" }; + yield return new object[] { MessageType.NewChatMembers, "new_chat_members" }; + yield return new object[] { MessageType.LeftChatMember, "left_chat_member" }; + yield return new object[] { MessageType.NewChatTitle, "new_chat_title" }; + yield return new object[] { MessageType.NewChatPhoto, "new_chat_photo" }; + yield return new object[] { MessageType.DeleteChatPhoto, "delete_chat_photo" }; + yield return new object[] { MessageType.GroupChatCreated, "group_chat_created" }; + yield return new object[] { MessageType.SupergroupChatCreated, "supergroup_chat_created" }; + yield return new object[] { MessageType.ChannelChatCreated, "channel_chat_created" }; + yield return new object[] { MessageType.MessageAutoDeleteTimerChanged, "message_auto_delete_timer_changed" }; + yield return new object[] { MessageType.MigrateToChatId, "migrate_to_chat_id" }; + yield return new object[] { MessageType.MigrateFromChatId, "migrate_from_chat_id" }; + yield return new object[] { MessageType.PinnedMessage, "pinned_message" }; + yield return new object[] { MessageType.Invoice, "invoice" }; + yield return new object[] { MessageType.SuccessfulPayment, "successful_payment" }; + yield return new object[] { MessageType.UsersShared, "users_shared" }; + yield return new object[] { MessageType.ChatShared, "chat_shared" }; + yield return new object[] { MessageType.ConnectedWebsite, "connected_website" }; + yield return new object[] { MessageType.WriteAccessAllowed, "write_access_allowed" }; + yield return new object[] { MessageType.PassportData, "passport_data" }; + yield return new object[] { MessageType.ProximityAlertTriggered, "proximity_alert_triggered" }; + yield return new object[] { MessageType.ForumTopicCreated, "forum_topic_created" }; + yield return new object[] { MessageType.ForumTopicEdited, "forum_topic_edited" }; + yield return new object[] { MessageType.ForumTopicClosed, "forum_topic_closed" }; + yield return new object[] { MessageType.ForumTopicReopened, "forum_topic_reopened" }; + yield return new object[] { MessageType.GeneralForumTopicHidden, "general_forum_topic_hidden" }; + yield return new object[] { MessageType.GeneralForumTopicUnhidden, "general_forum_topic_unhidden" }; + yield return new object[] { MessageType.GiveawayCreated, "giveaway_created" }; + yield return new object[] { MessageType.Giveaway, "giveaway" }; + yield return new object[] { MessageType.GiveawayWinners, "giveaway_winners" }; + yield return new object[] { MessageType.GiveawayCompleted, "giveaway_completed" }; + yield return new object[] { MessageType.VideoChatScheduled, "video_chat_scheduled" }; + yield return new object[] { MessageType.VideoChatStarted, "video_chat_started" }; + yield return new object[] { MessageType.VideoChatEnded, "video_chat_ended" }; + yield return new object[] { MessageType.VideoChatParticipantsInvited, "video_chat_participants_invited" }; + yield return new object[] { MessageType.WebAppData, "web_app_data" }; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } From 92750c5011c3c77c6f007f1cf4b1b54a36a8bc68 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 01:21:50 +0300 Subject: [PATCH 17/90] Chat Boost --- CHANGELOG.md | 7 +- .../Converters/ChatBoostSourceConverter.cs | 57 ++++++++++++ .../GetUserChatBoostsRequest.cs | 37 ++++++++ .../TelegramBotClientExtensions.ApiMethods.cs | 51 ++++++++--- src/Telegram.Bot/Types/ChatBoost.cs | 36 ++++++++ src/Telegram.Bot/Types/ChatBoostRemoved.cs | 35 +++++++ src/Telegram.Bot/Types/ChatBoostSource.cs | 91 +++++++++++++++++++ src/Telegram.Bot/Types/ChatBoostUpdated.cs | 20 ++++ src/Telegram.Bot/Types/Enums/UpdateType.cs | 10 ++ src/Telegram.Bot/Types/Update.cs | 48 ++++++---- src/Telegram.Bot/Types/UserChatBoosts.cs | 16 ++++ .../EnumConverter/UpdateTypeConverterTests.cs | 15 +-- 12 files changed, 386 insertions(+), 37 deletions(-) create mode 100644 src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs create mode 100644 src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs create mode 100644 src/Telegram.Bot/Types/ChatBoost.cs create mode 100644 src/Telegram.Bot/Types/ChatBoostRemoved.cs create mode 100644 src/Telegram.Bot/Types/ChatBoostSource.cs create mode 100644 src/Telegram.Bot/Types/ChatBoostUpdated.cs create mode 100644 src/Telegram.Bot/Types/UserChatBoosts.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index b7d9a3778..c43c39ac3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and the property `MessageReactionCount` in the class `Update`. The bot must expl - The property `AvailableReactions` to the class `Chat`. - The class `ExternalReplyInfo` and the property `ExternalReply` of type `ExternalReplyInfo` to the class `Message`, containing information about a message that is replied to by the current message, but can be from another chat or forum topic. -- Added the class `TextQuote` and the property `Quote` of type `TextQuote` to the class `Message`, +- The class `TextQuote` and the property `Quote` of type `TextQuote` to the class `Message`, which contains the part of the replied message text or caption that is quoted in the current message. - The class `ReplyParameters`. - The class `LinkPreviewOptions`. @@ -47,6 +47,11 @@ which contains the part of the replied message text or caption that is quoted in - New enum value `Blockquote` for `MessageEntityType`. - Request classes `DeleteMessagesRequest`, `ForwardMessagesRequest` and `CopyMessagesRequest`. - New methods `ITelegramBotClient.DeleteMessagesAsync`, `ITelegramBotClient.ForwardMessagesAsync` and `ITelegramBotClient.CopyMessagesAsync`. +- Updates about chat boost changes, represented by the classes `ChatBoostUpdated` and `ChatBoostRemoved` and the properties `ChatBoost` and `RemovedChatBoost` +in the class `Update`. The bot must be an administrator in the chat to receive these updates. +- The classes `ChatBoostSourcePremium`, `ChatBoostSourceGiftCode` and `ChatBoostSourceGiveaway`, representing different sources of a chat boost. +- The method `ITelegramBotClient.GetUserChatBoostsAsync` for obtaining the list of all active boosts a user has contributed to a chat. +- Request class `GetUserChatBoostsRequest` for obtaining the list of all active boosts a user has contributed to a chat. ### Changed diff --git a/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs b/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs new file mode 100644 index 000000000..76afd5464 --- /dev/null +++ b/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs @@ -0,0 +1,57 @@ +using System.Reflection; +using Newtonsoft.Json.Linq; + +namespace Telegram.Bot.Converters; + +internal class ChatBoostSourceConverter : JsonConverter +{ + static readonly TypeInfo BaseType = typeof(ChatBoostSource).GetTypeInfo(); + + public override bool CanWrite => false; + public override bool CanRead => true; + public override bool CanConvert(Type objectType) => + BaseType.IsAssignableFrom(objectType.GetTypeInfo()); + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + } + else + { + var jo = JObject.FromObject(value); + jo.WriteTo(writer); + } + } + + public override object? ReadJson( + JsonReader reader, + Type objectType, + object? existingValue, + JsonSerializer serializer) + { + var jo = JObject.Load(reader); + var type = jo["source"]?.Value(); + + if (type is null) + { + return null; + } + + var actualType = type switch + { + "premium" => typeof(ChatBoostSourcePremium), + "gift_code" => typeof(ChatBoostSourceGiftCode), + "giveaway" => typeof(ChatBoostSourceGiveaway), + _ => throw new JsonSerializationException($"Unknown chat boost source value of '{jo["source"]}'") + }; + + // Remove status because status property only has getter + jo.Remove("source"); + var value = Activator.CreateInstance(actualType)!; + serializer.Populate(jo.CreateReader(), value); + + return value; + } +} diff --git a/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs new file mode 100644 index 000000000..d257fe5f6 --- /dev/null +++ b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs @@ -0,0 +1,37 @@ +// ReSharper disable once CheckNamespace +namespace Telegram.Bot.Requests; + +/// +/// Use this method to get the list of boosts added to a chat by a user. +/// Requires administrator rights in the chat. +/// Returns a object. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class GetUserChatBoostsRequest : RequestBase +{ + /// + /// Unique identifier for the chat or username of the channel (in the format @channelusername) + /// + [JsonProperty(Required = Required.Always)] + public ChatId ChatId { get; } + + /// + /// Unique identifier of the target user + /// + [JsonProperty(Required = Required.Always)] + public long UserId { get; } + + /// + /// Initializes a new request with chatId and userId + /// + /// + /// Unique identifier for the chat or username of the channel (in the format @channelusername) + /// + /// Unique identifier of the target user + public GetUserChatBoostsRequest(ChatId chatId, long userId) + : base("getUserChatBoosts") + { + ChatId = chatId; + UserId = userId; + } +} diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index b456fe9f0..7db23fb83 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -3232,29 +3232,28 @@ await botClient.ThrowIfNull() .ConfigureAwait(false); /// - /// Use this method to set the result of an interaction with a Web App and send a corresponding message on - /// behalf of the user to the chat from which the query originated. On success, a - /// object is returned. + /// Use this method to get the list of boosts added to a chat by a user. + /// Requires administrator rights in the chat. /// /// An instance of - /// Unique identifier for the query to be answered - /// - /// An object describing the message to be sent + /// + /// Unique identifier for the chat or username of the channel (in the format @channelusername) + /// + /// + /// Unique identifier of the target user /// /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task AnswerWebAppQueryAsync( + /// Returns a object. + public static async Task GetUserChatBoostsAsync( this ITelegramBotClient botClient, - string webAppQueryId, - InlineQueryResult result, + ChatId chatId, + long userId, CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync( - request: new AnswerWebAppQueryRequest(webAppQueryId, result), - cancellationToken - ) + .MakeRequestAsync(request: new GetUserChatBoostsRequest(chatId, userId), cancellationToken) .ConfigureAwait(false); /// @@ -4665,6 +4664,32 @@ await botClient.ThrowIfNull() ) .ConfigureAwait(false); + /// + /// Use this method to set the result of an interaction with a Web App and send a corresponding message on + /// behalf of the user to the chat from which the query originated. On success, a + /// object is returned. + /// + /// An instance of + /// Unique identifier for the query to be answered + /// + /// An object describing the message to be sent + /// + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerWebAppQueryAsync( + this ITelegramBotClient botClient, + string webAppQueryId, + InlineQueryResult result, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync( + request: new AnswerWebAppQueryRequest(webAppQueryId, result), + cancellationToken + ) + .ConfigureAwait(false); + #endregion Inline mode #region Payments diff --git a/src/Telegram.Bot/Types/ChatBoost.cs b/src/Telegram.Bot/Types/ChatBoost.cs new file mode 100644 index 000000000..a0c80f586 --- /dev/null +++ b/src/Telegram.Bot/Types/ChatBoost.cs @@ -0,0 +1,36 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object contains information about a chat boost. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ChatBoost +{ + /// + /// Unique identifier of the boost + /// + [JsonProperty(Required = Required.Always)] + public string BoostId { get; } = default!; + + /// + /// Point in time when the chat was boosted + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime AddDate { get; } = default!; + + /// + /// Point in time when the boost will automatically expire, unless the booster's Telegram Premium subscription is prolonged + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime ExpirationDate { get; } = default!; + + /// + /// Source of the added boost + /// + [JsonProperty(Required = Required.Always)] + public ChatBoostSource Source { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/ChatBoostRemoved.cs b/src/Telegram.Bot/Types/ChatBoostRemoved.cs new file mode 100644 index 000000000..a82322f1a --- /dev/null +++ b/src/Telegram.Bot/Types/ChatBoostRemoved.cs @@ -0,0 +1,35 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object represents a boost removed from a chat. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ChatBoostRemoved +{ + /// + /// Chat which was boosted + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Unique identifier of the boost + /// + [JsonProperty(Required = Required.Always)] + public string BoostId { get; } = default!; + + /// + /// Point in time when the boost was removed + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime RemoveDate { get; } = default!; + + /// + /// Source of the removed boost + /// + [JsonProperty(Required = Required.Always)] + public ChatBoostSource Source { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/ChatBoostSource.cs b/src/Telegram.Bot/Types/ChatBoostSource.cs new file mode 100644 index 000000000..749073195 --- /dev/null +++ b/src/Telegram.Bot/Types/ChatBoostSource.cs @@ -0,0 +1,91 @@ +using Telegram.Bot.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object describes the source of a chat boost. It can be one of +/// +/// +/// +/// +/// +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +[JsonConverter(typeof(ChatBoostSourceConverter))] +public abstract class ChatBoostSource +{ + /// + /// Source of the boost + /// + [JsonProperty] + public abstract string Source { get; } +} + +/// +/// The boost was obtained by subscribing to Telegram Premium or by gifting a Telegram Premium subscription to another user. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public abstract class ChatBoostSourcePremium : ChatBoostSource +{ + /// + /// Source of the boost, always "premium" + /// + public override string Source => "premium"; + + /// + /// User that boosted the chat + /// + [JsonProperty(Required = Required.Always)] + public User User { get; } = default!; +} + +/// +/// The boost was obtained by the creation of Telegram Premium gift codes to boost a chat. +/// Each such code boosts the chat 4 times for the duration of the corresponding Telegram Premium subscription. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public abstract class ChatBoostSourceGiftCode : ChatBoostSource +{ + /// + /// Source of the boost, always "gift_code" + /// + public override string Source => "gift_code"; + + /// + /// User for which the gift code was created + /// + [JsonProperty(Required = Required.Always)] + public User User { get; } = default!; +} + +/// +/// The boost was obtained by the creation of a Telegram Premium giveaway. +/// This boosts the chat 4 times for the duration of the corresponding Telegram Premium subscription. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public abstract class ChatBoostSourceGiveaway : ChatBoostSource +{ + /// + /// Source of the boost, always "giveaway" + /// + public override string Source => "giveaway"; + + /// + /// Identifier of a message in the chat with the giveaway; the message could have been deleted already. + /// May be 0 if the message isn't sent yet. + /// + [JsonProperty(Required = Required.Always)] + public int GiveawayMessageId { get; } = default!; + + /// + /// Optional. User that won the prize in the giveaway if any + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public User? User { get; set; } + + /// + /// Optional. , if the giveaway was completed, but there was no user to win the prize + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? IsUnclaimed { get; set; } +} diff --git a/src/Telegram.Bot/Types/ChatBoostUpdated.cs b/src/Telegram.Bot/Types/ChatBoostUpdated.cs new file mode 100644 index 000000000..6c950599c --- /dev/null +++ b/src/Telegram.Bot/Types/ChatBoostUpdated.cs @@ -0,0 +1,20 @@ +namespace Telegram.Bot.Types; + +/// +/// This object represents a boost added to a chat or changed. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ChatBoostUpdated +{ + /// + /// Chat which was boosted + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Information about the chat boost + /// + [JsonProperty(Required = Required.Always)] + public ChatBoost Boost { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/Enums/UpdateType.cs b/src/Telegram.Bot/Types/Enums/UpdateType.cs index 8cd249831..c862d0587 100644 --- a/src/Telegram.Bot/Types/Enums/UpdateType.cs +++ b/src/Telegram.Bot/Types/Enums/UpdateType.cs @@ -90,4 +90,14 @@ public enum UpdateType /// The contains an /// MessageReactionCount, + + /// + /// The contains a + /// + ChatBoost, + + /// + /// The contains a + /// + RemovedChatBoost, } diff --git a/src/Telegram.Bot/Types/Update.cs b/src/Telegram.Bot/Types/Update.cs index 4ab6fa150..6ca576a86 100644 --- a/src/Telegram.Bot/Types/Update.cs +++ b/src/Telegram.Bot/Types/Update.cs @@ -128,6 +128,18 @@ public class Update [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public ChatJoinRequest? ChatJoinRequest { get; set; } + /// + /// Optional. A chat boost was added or changed. The bot must be an administrator in the chat to receive these updates. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ChatBoostUpdated? ChatBoost { get; set; } + + /// + /// Optional. A boost was removed from a chat. The bot must be an administrator in the chat to receive these updates. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ChatBoostRemoved? RemovedChatBoost { get; set; } + /// /// Gets the update type. /// @@ -136,22 +148,24 @@ public class Update /// public UpdateType Type => this switch { - { Message: not null } => UpdateType.Message, - { EditedMessage: not null } => UpdateType.EditedMessage, - { ChannelPost: not null } => UpdateType.ChannelPost, - { EditedChannelPost: not null } => UpdateType.EditedChannelPost, - { MessageReaction: not null } => UpdateType.MessageReaction, - { MessageReactionCount: not null } => UpdateType.MessageReactionCount, - { InlineQuery: not null } => UpdateType.InlineQuery, - { ChosenInlineResult: not null } => UpdateType.ChosenInlineResult, - { CallbackQuery: not null } => UpdateType.CallbackQuery, - { ShippingQuery: not null } => UpdateType.ShippingQuery, - { PreCheckoutQuery: not null } => UpdateType.PreCheckoutQuery, - { Poll: not null } => UpdateType.Poll, - { PollAnswer: not null } => UpdateType.PollAnswer, - { MyChatMember: not null } => UpdateType.MyChatMember, - { ChatMember: not null } => UpdateType.ChatMember, - { ChatJoinRequest: not null } => UpdateType.ChatJoinRequest, - _ => UpdateType.Unknown + { Message: not null } => UpdateType.Message, + { EditedMessage: not null } => UpdateType.EditedMessage, + { ChannelPost: not null } => UpdateType.ChannelPost, + { EditedChannelPost: not null } => UpdateType.EditedChannelPost, + { MessageReaction: not null } => UpdateType.MessageReaction, + { MessageReactionCount: not null } => UpdateType.MessageReactionCount, + { InlineQuery: not null } => UpdateType.InlineQuery, + { ChosenInlineResult: not null } => UpdateType.ChosenInlineResult, + { CallbackQuery: not null } => UpdateType.CallbackQuery, + { ShippingQuery: not null } => UpdateType.ShippingQuery, + { PreCheckoutQuery: not null } => UpdateType.PreCheckoutQuery, + { Poll: not null } => UpdateType.Poll, + { PollAnswer: not null } => UpdateType.PollAnswer, + { MyChatMember: not null } => UpdateType.MyChatMember, + { ChatMember: not null } => UpdateType.ChatMember, + { ChatJoinRequest: not null } => UpdateType.ChatJoinRequest, + { ChatBoost: not null } => UpdateType.ChatBoost, + { RemovedChatBoost: not null } => UpdateType.RemovedChatBoost, + _ => UpdateType.Unknown }; } diff --git a/src/Telegram.Bot/Types/UserChatBoosts.cs b/src/Telegram.Bot/Types/UserChatBoosts.cs new file mode 100644 index 000000000..30323cf5a --- /dev/null +++ b/src/Telegram.Bot/Types/UserChatBoosts.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace Telegram.Bot.Types; + +/// +/// This object represents a list of boosts added to a chat by a user. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class UserChatBoosts +{ + /// + /// The list of boosts added to the chat by the user + /// + [JsonProperty(Required = Required.Always)] + IEnumerable Boosts { get; } = default!; +} diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs index 6a031781a..545fc07b0 100644 --- a/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/UpdateTypeConverterTests.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; @@ -89,12 +90,14 @@ public IEnumerator GetEnumerator() { yield return new object[] { UpdateType.Unknown, "unknown" }; yield return new object[] { UpdateType.Message, "message" }; - yield return new object[] { UpdateType.InlineQuery, "inline_query" }; - yield return new object[] { UpdateType.ChosenInlineResult, "chosen_inline_result" }; - yield return new object[] { UpdateType.CallbackQuery, "callback_query" }; yield return new object[] { UpdateType.EditedMessage, "edited_message" }; yield return new object[] { UpdateType.ChannelPost, "channel_post" }; yield return new object[] { UpdateType.EditedChannelPost, "edited_channel_post" }; + yield return new object[] { UpdateType.MessageReaction, "message_reaction" }; + yield return new object[] { UpdateType.MessageReactionCount, "message_reaction_count" }; + yield return new object[] { UpdateType.InlineQuery, "inline_query" }; + yield return new object[] { UpdateType.ChosenInlineResult, "chosen_inline_result" }; + yield return new object[] { UpdateType.CallbackQuery, "callback_query" }; yield return new object[] { UpdateType.ShippingQuery, "shipping_query" }; yield return new object[] { UpdateType.PreCheckoutQuery, "pre_checkout_query" }; yield return new object[] { UpdateType.Poll, "poll" }; @@ -102,10 +105,10 @@ public IEnumerator GetEnumerator() yield return new object[] { UpdateType.MyChatMember, "my_chat_member" }; yield return new object[] { UpdateType.ChatMember, "chat_member" }; yield return new object[] { UpdateType.ChatJoinRequest, "chat_join_request" }; - yield return new object[] { UpdateType.MessageReaction, "message_reaction" }; - yield return new object[] { UpdateType.MessageReactionCount, "message_reaction_count" }; + yield return new object[] { UpdateType.ChatBoost, "chat_boost" }; + yield return new object[] { UpdateType.RemovedChatBoost, "removed_chat_boost" }; } - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); } } From 2e3b0a1aed3400522feb6752eb0863c929bbaaff Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 01:56:13 +0300 Subject: [PATCH 18/90] Giveaway --- src/Telegram.Bot/Types/Enums/MessageType.cs | 20 ++++ src/Telegram.Bot/Types/Giveaway.cs | 62 ++++++++++ src/Telegram.Bot/Types/GiveawayCompleted.cs | 26 ++++ src/Telegram.Bot/Types/GiveawayCreated.cs | 10 ++ src/Telegram.Bot/Types/GiveawayWinners.cs | 77 ++++++++++++ src/Telegram.Bot/Types/Message.cs | 124 ++++++++++++-------- 6 files changed, 271 insertions(+), 48 deletions(-) create mode 100644 src/Telegram.Bot/Types/Giveaway.cs create mode 100644 src/Telegram.Bot/Types/GiveawayCompleted.cs create mode 100644 src/Telegram.Bot/Types/GiveawayCreated.cs create mode 100644 src/Telegram.Bot/Types/GiveawayWinners.cs diff --git a/src/Telegram.Bot/Types/Enums/MessageType.cs b/src/Telegram.Bot/Types/Enums/MessageType.cs index 7c1109502..add2ad014 100644 --- a/src/Telegram.Bot/Types/Enums/MessageType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageType.cs @@ -240,4 +240,24 @@ public enum MessageType /// The contains /// Story, + + /// + /// The contains a + /// + GiveawayCreated, + + /// + /// The contains a + /// + Giveaway, + + /// + /// The contains a + /// + GiveawayWinners, + + /// + /// The contains a + /// + GiveawayCompleted, } diff --git a/src/Telegram.Bot/Types/Giveaway.cs b/src/Telegram.Bot/Types/Giveaway.cs new file mode 100644 index 000000000..2983fc1ca --- /dev/null +++ b/src/Telegram.Bot/Types/Giveaway.cs @@ -0,0 +1,62 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object represents a message about a scheduled giveaway. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class Giveaway +{ + /// + /// The list of chats which the user must join to participate in the giveaway + /// + [JsonProperty(Required = Required.Always)] + public Chat[] Chats { get; } = default!; + + /// + /// Point in time when winners of the giveaway will be selected + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime WinnersSelectionDate { get; } = default!; + + /// + /// The number of users which are supposed to be selected as winners of the giveaway + /// + [JsonProperty(Required = Required.Always)] + public int WinnerCount { get; } = default!; + + /// + /// Optional. , if only users who join the chats after the giveaway started should be eligible to win + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? OnlyNewMembers { get; set; } + + /// + /// Optional., if the list of giveaway winners will be visible to everyone + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? HasPublicWinners { get; set; } + + /// + /// Optional. Description of additional giveaway prize + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? PrizeDescription { get; set; } + + /// + /// Optional.A list of two-letter ISO 3166-1 alpha-2 + /// country codes indicating the countries from which eligible users for the giveaway must come. + /// If empty, then all users can participate in the giveaway. + /// Users with a phone number that was bought on Fragment can always participate in giveaways. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string[]? CountryCodes { get; set; } + + /// + /// Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? PremiumSubscriptionMonthCount { get; set; } +} diff --git a/src/Telegram.Bot/Types/GiveawayCompleted.cs b/src/Telegram.Bot/Types/GiveawayCompleted.cs new file mode 100644 index 000000000..7f0ed4d8e --- /dev/null +++ b/src/Telegram.Bot/Types/GiveawayCompleted.cs @@ -0,0 +1,26 @@ +namespace Telegram.Bot.Types; + +/// +/// This object represents a service message about the completion of a giveaway without public winners. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class GiveawayCompleted +{ + /// + /// Number of winners in the giveaway + /// + [JsonProperty(Required = Required.Always)] + public int WinnerCount { get; } = default!; + + /// + /// Optional. Number of undistributed prizes + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? UnclaimedPrizeCount { get; set; } + + /// + /// Optional. Message with the giveaway that was completed, if it wasn't deleted + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Message? GiveawayMessage { get; set; } +} diff --git a/src/Telegram.Bot/Types/GiveawayCreated.cs b/src/Telegram.Bot/Types/GiveawayCreated.cs new file mode 100644 index 000000000..1bf8aecbd --- /dev/null +++ b/src/Telegram.Bot/Types/GiveawayCreated.cs @@ -0,0 +1,10 @@ +namespace Telegram.Bot.Types; + +/// +/// This object represents a service message about the creation of a scheduled giveaway. +/// Currently holds no information. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class GiveawayCreated +{ +} diff --git a/src/Telegram.Bot/Types/GiveawayWinners.cs b/src/Telegram.Bot/Types/GiveawayWinners.cs new file mode 100644 index 000000000..60e7f7fd0 --- /dev/null +++ b/src/Telegram.Bot/Types/GiveawayWinners.cs @@ -0,0 +1,77 @@ +using Newtonsoft.Json.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object represents a message about the completion of a giveaway with public winners. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class GiveawayWinners +{ + /// + /// The chat that created the giveaway + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Identifier of the message with the giveaway in the chat + /// + [JsonProperty(Required = Required.Always)] + public int GiveawayMessageId { get; } = default!; + + /// + /// Point in time when winners of the giveaway were selected + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public DateTime WinnersSelectionDate { get; } = default!; + + /// + /// Total number of winners in the giveaway + /// + [JsonProperty(Required = Required.Always)] + public int WinnerCount { get; } = default!; + + /// + /// List of up to 100 winners of the giveaway + /// + [JsonProperty(Required = Required.Always)] + public User[] Winners { get; } = default!; + + /// + /// Optional. The number of other chats the user had to join in order to be eligible for the giveaway + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? AdditionalChatCount { get; set; } + + /// + /// Optional. The number of months the Telegram Premium subscription won from the giveaway will be active for + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? PremiumSubscriptionMonthCount { get; set; } + + /// + /// Optional. Number of undistributed prizes + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? UnclaimedPrizeCount { get; set; } + + /// + /// Optional. , if only users who had joined the chats after the giveaway started were eligible to win + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? OnlyNewMembers { get; set; } + + /// + /// Optional. , if the giveaway was canceled because the payment for it was refunded + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? WasRefunded { get; set; } + + /// + /// Optional. Description of additional giveaway prize + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? PrizeDescription { get; set; } +} diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index e1259a4ea..dfec80c72 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -443,6 +443,30 @@ Caption is null [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public GeneralForumTopicUnhidden? GeneralForumTopicUnhidden { get; set; } + /// + /// Optional. Service message: a scheduled giveaway was created + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public GiveawayCreated? GiveawayCreated { get; set; } + + /// + /// Optional. The message is a scheduled giveaway message + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Giveaway? Giveaway { get; set; } + + /// + /// Optional. A giveaway with public winners was completed + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public GiveawayWinners? GiveawayWinners { get; set; } + + /// + /// Optional. Service message: a giveaway without public winners was completed + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public GiveawayCompleted? GiveawayCompleted { get; set; } + /// /// Optional. Service message: video chat scheduled /// @@ -489,53 +513,57 @@ Caption is null public MessageType Type => this switch { - { Text: { } } => MessageType.Text, - { Photo: { } } => MessageType.Photo, - { Audio: { } } => MessageType.Audio, - { Video: { } } => MessageType.Video, - { Voice: { } } => MessageType.Voice, - { Animation: { } } => MessageType.Animation, - { Document: { } } => MessageType.Document, - { Sticker: { } } => MessageType.Sticker, - { Story: { } } => MessageType.Story, - // Venue also contains Location - { Location: { } } and { Venue: null } => MessageType.Location, - { Venue: { } } => MessageType.Venue, - { Contact: { } } => MessageType.Contact, - { Game: { } } => MessageType.Game, - { VideoNote: { } } => MessageType.VideoNote, - { Invoice: { } } => MessageType.Invoice, - { SuccessfulPayment: { } } => MessageType.SuccessfulPayment, - { ConnectedWebsite: { } } => MessageType.WebsiteConnected, - { NewChatMembers: { Length: > 0 } } => MessageType.ChatMembersAdded, - { LeftChatMember: { } } => MessageType.ChatMemberLeft, - { NewChatTitle: { } } => MessageType.ChatTitleChanged, - { NewChatPhoto: { } } => MessageType.ChatPhotoChanged, - { PinnedMessage: { } } => MessageType.MessagePinned, - { DeleteChatPhoto: { } } => MessageType.ChatPhotoDeleted, - { GroupChatCreated: { } } => MessageType.GroupCreated, - { SupergroupChatCreated: { } } => MessageType.SupergroupCreated, - { ChannelChatCreated: { } } => MessageType.ChannelCreated, - { MigrateToChatId: { } } => MessageType.MigratedToSupergroup, - { MigrateFromChatId: { } } => MessageType.MigratedFromGroup, - { Poll: { } } => MessageType.Poll, - { Dice: { } } => MessageType.Dice, - { MessageAutoDeleteTimerChanged: { } } => MessageType.MessageAutoDeleteTimerChanged, - { ProximityAlertTriggered: { } } => MessageType.ProximityAlertTriggered, - { VideoChatScheduled: { } } => MessageType.VideoChatScheduled, - { VideoChatStarted: { } } => MessageType.VideoChatStarted, - { VideoChatEnded: { } } => MessageType.VideoChatEnded, - { VideoChatParticipantsInvited: { } } => MessageType.VideoChatParticipantsInvited, - { WebAppData: { } } => MessageType.WebAppData, - { ForumTopicCreated: { } } => MessageType.ForumTopicCreated, - { ForumTopicEdited: { } } => MessageType.ForumTopicEdited, - { ForumTopicClosed: { } } => MessageType.ForumTopicClosed, - { ForumTopicReopened: { } } => MessageType.ForumTopicReopened, - { GeneralForumTopicHidden: { } } => MessageType.GeneralForumTopicHidden, - { GeneralForumTopicUnhidden: { } } => MessageType.GeneralForumTopicUnhidden, - { WriteAccessAllowed: { } } => MessageType.WriteAccessAllowed, - { UserShared: { } } => MessageType.UserShared, - { ChatShared: { } } => MessageType.ChatShared, - _ => MessageType.Unknown + { Text: not null } => MessageType.Text, + { Animation: not null } => MessageType.Animation, + { Audio: not null } => MessageType.Audio, + { Document: not null } => MessageType.Document, + { Photo: not null } => MessageType.Photo, + { Sticker: not null } => MessageType.Sticker, + { Story: not null } => MessageType.Story, + { Video: not null } => MessageType.Video, + { VideoNote: not null } => MessageType.VideoNote, + { Voice: not null } => MessageType.Voice, + { Contact: not null } => MessageType.Contact, + { Dice: not null } => MessageType.Dice, + { Game: not null } => MessageType.Game, + { Poll: not null } => MessageType.Poll, + { Venue: not null } => MessageType.Venue, + { Location: not null } and { Venue: null } => MessageType.Location, + { NewChatMembers.Length: > 0 } => MessageType.NewChatMembers, + { LeftChatMember: not null } => MessageType.LeftChatMember, + { NewChatTitle: not null } => MessageType.NewChatTitle, + { NewChatPhoto: not null } => MessageType.NewChatPhoto, + { DeleteChatPhoto: not null } => MessageType.DeleteChatPhoto, + { GroupChatCreated: not null } => MessageType.GroupChatCreated, + { SupergroupChatCreated: not null } => MessageType.SupergroupChatCreated, + { ChannelChatCreated: not null } => MessageType.ChannelChatCreated, + { MessageAutoDeleteTimerChanged: not null } => MessageType.MessageAutoDeleteTimerChanged, + { MigrateToChatId: not null } => MessageType.MigrateToChatId, + { MigrateFromChatId: not null } => MessageType.MigrateFromChatId, + { PinnedMessage: not null } => MessageType.PinnedMessage, + { Invoice: not null } => MessageType.Invoice, + { SuccessfulPayment: not null } => MessageType.SuccessfulPayment, + { UsersShared: not null } => MessageType.UsersShared, + { ChatShared: not null } => MessageType.ChatShared, + { ConnectedWebsite: not null } => MessageType.ConnectedWebsite, + { WriteAccessAllowed: not null } => MessageType.WriteAccessAllowed, + { PassportData: not null } => MessageType.PassportData, + { ProximityAlertTriggered: not null } => MessageType.ProximityAlertTriggered, + { ForumTopicCreated: not null } => MessageType.ForumTopicCreated, + { ForumTopicEdited: not null } => MessageType.ForumTopicEdited, + { ForumTopicClosed: not null } => MessageType.ForumTopicClosed, + { ForumTopicReopened: not null } => MessageType.ForumTopicReopened, + { GeneralForumTopicHidden: not null } => MessageType.GeneralForumTopicHidden, + { GeneralForumTopicUnhidden: not null } => MessageType.GeneralForumTopicUnhidden, + { GiveawayCreated: not null } => MessageType.GiveawayCreated, + { Giveaway: not null } => MessageType.Giveaway, + { GiveawayWinners: not null } => MessageType.GiveawayWinners, + { GiveawayCompleted: not null } => MessageType.GiveawayCompleted, + { VideoChatScheduled: not null } => MessageType.VideoChatScheduled, + { VideoChatStarted: not null } => MessageType.VideoChatStarted, + { VideoChatEnded: not null } => MessageType.VideoChatEnded, + { VideoChatParticipantsInvited: not null } => MessageType.VideoChatParticipantsInvited, + { WebAppData: not null } => MessageType.WebAppData, + _ => MessageType.Unknown }; } From 6865bf613f830cf3f493c3100f19b7c75aabe02f Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 01:56:49 +0300 Subject: [PATCH 19/90] Giveaway: update CHANGELOG --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c43c39ac3..56105484e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,11 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - The classes `ChatBoostSourcePremium`, `ChatBoostSourceGiftCode` and `ChatBoostSourceGiveaway`, representing different sources of a chat boost. - The method `ITelegramBotClient.GetUserChatBoostsAsync` for obtaining the list of all active boosts a user has contributed to a chat. - Request class `GetUserChatBoostsRequest` for obtaining the list of all active boosts a user has contributed to a chat. +- The class `Giveaway` and the property `Giveaway` to the class `Message` for messages about scheduled giveaways. +- The class `GiveawayCreated` and the property `GiveawayCreated` to the class `Message` for service messages about the creation of a scheduled giveaway. +- The class `GiveawayWinners` and the property `GiveawayWinners` to the class `Message` for messages about the completion of a giveaway with public winners. +- The class `GiveawayCompleted` and the property `GiveawayCompleted` to the class `Message` for service messages about the completion of a giveaway without public winners. +- New `MessageType` enum members: `Giveaway`, `GiveawayCreated`, `GiveawayWinners` and `GiveawayCompleted` ### Changed From 3e4b17124a0e8e5c6b1e39219526e1329f63acf6 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 02:44:19 +0300 Subject: [PATCH 20/90] Other Changes --- CHANGELOG.md | 7 + .../MaybeInaccessibleMessageConverter.cs | 54 +++++++ .../Converters/MessageOriginConverter.cs | 58 +++++++ src/Telegram.Bot/Types/CallbackQuery.cs | 5 +- src/Telegram.Bot/Types/Chat.cs | 38 +++++ src/Telegram.Bot/Types/InaccessibleMessage.cs | 26 ++++ .../Types/MaybeInaccessibleMessage.cs | 21 +++ src/Telegram.Bot/Types/Message.cs | 10 +- src/Telegram.Bot/Types/MessageOrigin.cs | 142 ++++++++++++++++++ 9 files changed, 353 insertions(+), 8 deletions(-) create mode 100644 src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs create mode 100644 src/Telegram.Bot/Converters/MessageOriginConverter.cs create mode 100644 src/Telegram.Bot/Types/InaccessibleMessage.cs create mode 100644 src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs create mode 100644 src/Telegram.Bot/Types/MessageOrigin.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 56105484e..324965081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,9 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - The class `GiveawayWinners` and the property `GiveawayWinners` to the class `Message` for messages about the completion of a giveaway with public winners. - The class `GiveawayCompleted` and the property `GiveawayCompleted` to the class `Message` for service messages about the completion of a giveaway without public winners. - New `MessageType` enum members: `Giveaway`, `GiveawayCreated`, `GiveawayWinners` and `GiveawayCompleted` +- The properties `AccentColorId`, `BackgroundCustomEmojiId`, `ProfileAccentColorId`, and `ProfileBackgroundCustomEmojiId` to the class `Chat`. +- The property `HasVisibleHistory` to the class `Chat`. +- Classes `MaybeInaccessibleMessage` and `InaccessibleMessage`. ### Changed @@ -107,6 +110,10 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Renamed the class `UserShared` to `UsersShared` and changed the property `UserId` to `UserIds`. - Replaced the property `UserShared` in the class Message with the property `UsersShared`. - Replaced enum member `MessageType.UserShared` with `MessageType.UsersShared` +- The class `MessageOrigin` and replaced the fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName` +and `ForwardDate` with the field `ForwardOrigin` of type `MessageOrigin in the class `Message`. +- Type of the property `Message` of the class `CallbackQuery` to `MaybeInaccessibleMessage` +- Type of the property `PinnedMessage` of the class `Message` to `MaybeInaccessibleMessage`. ## [v20.0.0] - Unreleased diff --git a/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs b/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs new file mode 100644 index 000000000..29a6173b0 --- /dev/null +++ b/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs @@ -0,0 +1,54 @@ +using System.Reflection; +using Newtonsoft.Json.Linq; + +namespace Telegram.Bot.Converters; + +internal class MaybeInaccessibleMessageConverter : JsonConverter +{ + static readonly TypeInfo BaseType = typeof(MaybeInaccessibleMessage).GetTypeInfo(); + + public override bool CanWrite => false; + public override bool CanRead => true; + public override bool CanConvert(Type objectType) => + BaseType.IsAssignableFrom(objectType.GetTypeInfo()); + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + } + else + { + var jo = JObject.FromObject(value); + jo.WriteTo(writer); + } + } + + public override object? ReadJson( + JsonReader reader, + Type objectType, + object? existingValue, + JsonSerializer serializer) + { + var jo = JObject.Load(reader); + var date = jo["date"]?.Value(); + + if (date is null) + { + return null; + } + + var actualType = date switch + { + 0 => typeof(Message), + _ => typeof(InaccessibleMessage), + }; + + // Remove status because status property only has getter + var value = Activator.CreateInstance(actualType)!; + serializer.Populate(jo.CreateReader(), value); + + return value; + } +} diff --git a/src/Telegram.Bot/Converters/MessageOriginConverter.cs b/src/Telegram.Bot/Converters/MessageOriginConverter.cs new file mode 100644 index 000000000..1143264a8 --- /dev/null +++ b/src/Telegram.Bot/Converters/MessageOriginConverter.cs @@ -0,0 +1,58 @@ +using System.Reflection; +using Newtonsoft.Json.Linq; + +namespace Telegram.Bot.Converters; + +internal class MessageOriginConverter : JsonConverter +{ + static readonly TypeInfo BaseType = typeof(MessageOrigin).GetTypeInfo(); + + public override bool CanWrite => false; + public override bool CanRead => true; + public override bool CanConvert(Type objectType) => + BaseType.IsAssignableFrom(objectType.GetTypeInfo()); + + public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) + { + if (value is null) + { + writer.WriteNull(); + } + else + { + var jo = JObject.FromObject(value); + jo.WriteTo(writer); + } + } + + public override object? ReadJson( + JsonReader reader, + Type objectType, + object? existingValue, + JsonSerializer serializer) + { + var jo = JObject.Load(reader); + var type = jo["type"]?.Value(); + + if (type is null) + { + return null; + } + + var actualType = type switch + { + "user" => typeof(MessageOriginUser), + "hidden_user" => typeof(MessageOriginHiddenUser), + "chat" => typeof(MessageOriginChat), + "channel" => typeof(MessageOriginChannel), + _ => throw new JsonSerializationException($"Unknown message origin type value of '{jo["type"]}'") + }; + + // Remove status because status property only has getter + jo.Remove("type"); + var value = Activator.CreateInstance(actualType)!; + serializer.Populate(jo.CreateReader(), value); + + return value; + } +} diff --git a/src/Telegram.Bot/Types/CallbackQuery.cs b/src/Telegram.Bot/Types/CallbackQuery.cs index 502f6cd56..e3eae6e60 100644 --- a/src/Telegram.Bot/Types/CallbackQuery.cs +++ b/src/Telegram.Bot/Types/CallbackQuery.cs @@ -31,11 +31,10 @@ public class CallbackQuery public User From { get; set; } = default!; /// - /// Optional. Description with the callback button that originated the query. Note that message content and - /// message date will not be available if the message is too old + /// Optional. Message sent by the bot with the callback button that originated the query /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public Message? Message { get; set; } + public MaybeInaccessibleMessage? Message { get; set; } /// /// Optional. Identifier of the message sent via the bot in inline mode, that originated the query diff --git a/src/Telegram.Bot/Types/Chat.cs b/src/Telegram.Bot/Types/Chat.cs index 67c6ff3d0..19e02cad1 100644 --- a/src/Telegram.Bot/Types/Chat.cs +++ b/src/Telegram.Bot/Types/Chat.cs @@ -75,6 +75,37 @@ public class Chat [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public ReactionType[]? AvailableReactions { get; set; } + /// + /// Optional. Identifier of the accent color + /// for the chat name and backgrounds of the chat photo, reply header, and link preview. + /// See accent colors for more details. Returned only in . + /// Always returned in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? AccentColorId { get; set; } + + /// + /// Optional. Custom emoji identifier of emoji chosen by the chat for the reply header and link preview background. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? BackgroundCustomEmojiId { get; set; } + + /// + /// Optional. Identifier of the accent color for the chat's profile background. + /// See profile accent colors for more details. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? ProfileAccentColorId { get; set; } + + /// + /// Optional. Custom emoji identifier of the emoji chosen by the chat for its profile background. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? ProfileBackgroundCustomEmojiId { get; set; } + /// /// Optional. Custom emoji identifier of emoji status of the other party in a private chat. /// Returned only in . @@ -182,6 +213,13 @@ public class Chat [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? HasHiddenMembers { get; set; } + /// + /// Optional. , if new chat members will have access to old messages; available only to chat administrators. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public bool? HasVisibleHistory { get; set; } + /// /// Optional. , if messages from the chat can't be forwarded to other chats. /// Returned only in . diff --git a/src/Telegram.Bot/Types/InaccessibleMessage.cs b/src/Telegram.Bot/Types/InaccessibleMessage.cs new file mode 100644 index 000000000..9945742f5 --- /dev/null +++ b/src/Telegram.Bot/Types/InaccessibleMessage.cs @@ -0,0 +1,26 @@ +namespace Telegram.Bot.Types; + +/// +/// This object describes a message that was deleted or is otherwise inaccessible to the bot. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class InaccessibleMessage +{ + /// + /// Chat the message belonged to + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Unique message identifier inside the chat + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } = default!; + + /// + /// Always 0. The field can be used to differentiate regular and inaccessible messages. + /// + [JsonProperty(Required = Required.Always)] + public int Date { get; } = default!; +} diff --git a/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs new file mode 100644 index 000000000..84daadca4 --- /dev/null +++ b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs @@ -0,0 +1,21 @@ +using Telegram.Bot.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object describes a message that can be inaccessible to the bot. It can be one of +/// +/// +/// +/// +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +[JsonConverter(typeof(MaybeInaccessibleMessageConverter))] +public abstract class MaybeInaccessibleMessage +{ + /// + /// Date the message was sent. It is always a positive number, representing a valid date. + /// + [JsonProperty] + public abstract int Date { get; } +} diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index dfec80c72..2ec511264 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -54,10 +54,10 @@ public class Message public Chat Chat { get; set; } = default!; /// - /// Optional. For forwarded messages, sender of the original message + ///Optional. Information about the original message for forwarded messages /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public User? ForwardFrom { get; set; } + public MessageOrigin? ForwardOrigin { get; set; } /// /// Optional. , if the message is sent to a forum topic @@ -351,11 +351,11 @@ Caption is null public long? MigrateFromChatId { get; set; } /// - /// Optional. Specified message was pinned. Note that the Message object in this field will not contain - /// further fields even if it is itself a reply. + /// Optional. Specified message was pinned. Note that the object in this field + /// will not contain further fields even if it itself is a reply. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public Message? PinnedMessage { get; set; } + public MaybeInaccessibleMessage? PinnedMessage { get; set; } /// /// Optional. Message is an invoice for a diff --git a/src/Telegram.Bot/Types/MessageOrigin.cs b/src/Telegram.Bot/Types/MessageOrigin.cs new file mode 100644 index 000000000..dd02b5af5 --- /dev/null +++ b/src/Telegram.Bot/Types/MessageOrigin.cs @@ -0,0 +1,142 @@ +using Newtonsoft.Json.Converters; +using Telegram.Bot.Converters; + +namespace Telegram.Bot.Types; + +/// +/// This object describes the origin of a message. It can be one of +/// +/// +/// +/// +/// +/// +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +[JsonConverter(typeof(MessageOriginConverter))] +public abstract class MessageOrigin +{ + /// + /// Type of the message origin + /// + [JsonProperty] + public abstract string Type { get; } + + /// + /// Date the message was sent originally + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public abstract DateTime Date { get; } +} + +/// +/// The message was originally sent by a known user. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageOriginUser : MessageOrigin +{ + /// + /// Type of the message origin, always "user" + /// + public override string Type => "user"; + + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public override DateTime Date { get; } + + /// + /// User that sent the message originally + /// + [JsonProperty(Required = Required.Always)] + public User SenderUser { get; } = default!; +} + +/// +/// The message was originally sent by an unknown user. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageOriginHiddenUser : MessageOrigin +{ + /// + /// Type of the message origin, always "hidden_user" + /// + public override string Type => "hidden_user"; + + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public override DateTime Date { get; } + + /// + /// Name of the user that sent the message originally + /// + [JsonProperty(Required = Required.Always)] + public string SenderUserName { get; } = default!; +} + +/// +/// The message was originally sent on behalf of a chat to a group chat. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageOriginChat : MessageOrigin +{ + /// + /// Type of the message origin, always "chat" + /// + public override string Type => "chat"; + + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public override DateTime Date { get; } + + /// + /// Chat that sent the message originally + /// + [JsonProperty(Required = Required.Always)] + public Chat SenderChat { get; } = default!; + + /// + /// Optional. For messages originally sent by an anonymous chat administrator, + /// original message author signature + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? AuthorSignature { get; set; } +} + +/// +/// The message was originally sent to a channel chat. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class MessageOriginChannel : MessageOrigin +{ + /// + /// Type of the message origin, always "channel" + /// + public override string Type => "channel"; + + /// + [JsonProperty(Required = Required.Always)] + [JsonConverter(typeof(UnixDateTimeConverter))] + public override DateTime Date { get; } + + /// + /// Channel chat to which the message was originally sent + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; } = default!; + + /// + /// Unique message identifier inside the chat + /// + [JsonProperty(Required = Required.Always)] + public int MessageId { get; } = default!; + + /// + /// Optional. Signature of the original post author + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? AuthorSignature { get; set; } +} From e8fa20559691fd2c695bce8cc5e781f7535e3cf6 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 02:45:06 +0300 Subject: [PATCH 21/90] Fix spelling --- .../Requests/Abstractions/Documentation.cs | 2 +- src/Telegram.Bot/Types/Enums/MessageType.cs | 99 ++++++++++--------- src/Telegram.Bot/Types/Enums/UpdateType.cs | 32 +++--- src/Telegram.Bot/Types/ExternalReplyInfo.cs | 2 +- 4 files changed, 70 insertions(+), 65 deletions(-) diff --git a/src/Telegram.Bot/Requests/Abstractions/Documentation.cs b/src/Telegram.Bot/Requests/Abstractions/Documentation.cs index ff2d67e2b..f353e976f 100644 --- a/src/Telegram.Bot/Requests/Abstractions/Documentation.cs +++ b/src/Telegram.Bot/Requests/Abstractions/Documentation.cs @@ -1,6 +1,6 @@ #nullable disable #pragma warning disable 169 -#pragma warning disable CA1823 +#pragma warning disable IDE0051 using Telegram.Bot.Types.ReplyMarkups; diff --git a/src/Telegram.Bot/Types/Enums/MessageType.cs b/src/Telegram.Bot/Types/Enums/MessageType.cs index add2ad014..2434c1b42 100644 --- a/src/Telegram.Bot/Types/Enums/MessageType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageType.cs @@ -12,217 +12,217 @@ public enum MessageType Unknown = 0, /// - /// The contains text + /// The contains /// Text, /// - /// The contains a + /// The contains a /// Photo, /// - /// The contains an + /// The contains an /// Audio, /// - /// The contains a + /// The contains a /// Video, /// - /// The contains a + /// The contains a /// Voice, /// - /// The contains a + /// The contains a /// Document, /// - /// The contains a + /// The contains a /// Sticker, /// - /// The contains a + /// The contains a /// Location, /// - /// The contains a + /// The contains a /// Contact, /// - /// The contains a + /// The contains a /// Venue, /// - /// The contains a + /// The contains a /// Game, /// - /// The contains a + /// The contains a /// VideoNote, /// - /// The contains a + /// The contains an /// Invoice, /// - /// The contains a + /// The contains a /// SuccessfulPayment, /// /// The contains a /// - WebsiteConnected, + ConnectedWebsite, /// /// The contains a /// - ChatMembersAdded, + NewChatMembers, /// /// The contains a /// - ChatMemberLeft, + LeftChatMember, /// /// The contains a /// - ChatTitleChanged, + NewChatTitle, /// /// The contains a /// - ChatPhotoChanged, + NewChatPhoto, /// /// The contains a /// - MessagePinned, + PinnedMessage, /// /// The contains a /// - ChatPhotoDeleted, + DeleteChatPhoto, /// /// The contains a /// - GroupCreated, + GroupChatCreated, /// /// The contains a /// - SupergroupCreated, + SupergroupChatCreated, /// /// The contains a /// - ChannelCreated, + ChannelChatCreated, /// - /// The contains non-default + /// The contains a /// - MigratedToSupergroup, + MigrateFromChatId, /// - /// The contains non-default + /// The contains a /// - MigratedFromGroup, + MigrateToChatId, /// - /// The contains + /// The contains a /// Poll, /// - /// The contains + /// The contains a /// Dice, /// - /// The contains + /// The contains a /// MessageAutoDeleteTimerChanged, /// - /// The contains + /// The contains a /// ProximityAlertTriggered, /// - /// The contains + /// The contains a /// WebAppData, /// - /// The contains + /// The contains a /// VideoChatScheduled, /// - /// The contains + /// The contains a /// VideoChatStarted, /// - /// The contains + /// The contains a /// VideoChatEnded, /// - /// The contains + /// The contains a /// VideoChatParticipantsInvited, /// - /// The contains + /// The contains a /// Animation, /// - /// The contains + /// The contains a /// ForumTopicCreated, /// - /// The contains + /// The contains a /// ForumTopicClosed, /// - /// The contains + /// The contains a /// ForumTopicReopened, /// - /// The contains + /// The contains a /// ForumTopicEdited, /// - /// The contains + /// The contains a /// GeneralForumTopicHidden, /// - /// The contains + /// The contains a /// GeneralForumTopicUnhidden, /// - /// The contains + /// The contains a /// WriteAccessAllowed, @@ -232,15 +232,20 @@ public enum MessageType UsersShared, /// - /// The contains + /// The contains a /// ChatShared, /// - /// The contains + /// The contains a /// Story, + /// + /// The contains a + /// + PassportData, + /// /// The contains a /// diff --git a/src/Telegram.Bot/Types/Enums/UpdateType.cs b/src/Telegram.Bot/Types/Enums/UpdateType.cs index c862d0587..f689721f3 100644 --- a/src/Telegram.Bot/Types/Enums/UpdateType.cs +++ b/src/Telegram.Bot/Types/Enums/UpdateType.cs @@ -12,82 +12,82 @@ public enum UpdateType Unknown = 0, /// - /// The contains a . + /// The contains a . /// Message, /// - /// The contains an . + /// The contains an . /// InlineQuery, /// - /// The contains a . + /// The contains a . /// ChosenInlineResult, /// - /// The contains a + /// The contains a /// CallbackQuery, /// - /// The contains an edited + /// The contains /// EditedMessage, /// - /// The contains a channel post + /// The contains a /// ChannelPost, /// - /// The contains an edited channel post + /// The contains /// EditedChannelPost, /// - /// The contains an + /// The contains a /// ShippingQuery, /// - /// The contains an + /// The contains a /// PreCheckoutQuery, /// - /// The contains an + /// The contains a /// Poll, /// - /// The contains an + /// The contains a /// PollAnswer, /// - /// The contains an + /// The contains a /// MyChatMember, /// - /// The contains an + /// The contains a /// ChatMember, /// - /// The contains an + /// The contains a /// ChatJoinRequest, /// - /// The contains an + /// The contains a /// MessageReaction, /// - /// The contains an + /// The contains a /// MessageReactionCount, diff --git a/src/Telegram.Bot/Types/ExternalReplyInfo.cs b/src/Telegram.Bot/Types/ExternalReplyInfo.cs index 9d06fbf8e..9dec272fa 100644 --- a/src/Telegram.Bot/Types/ExternalReplyInfo.cs +++ b/src/Telegram.Bot/Types/ExternalReplyInfo.cs @@ -31,7 +31,7 @@ public class ExternalReplyInfo /// Optional.Options used for link preview generation for the original message, if it is a text message /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public LinkPreviewOptions LinkPreviewOptions { get; set; } + public LinkPreviewOptions? LinkPreviewOptions { get; set; } /// /// Optional. Message is an animation, information about the animation From ed4c92947257f01eff546717ed2d4295e0494c7a Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 05:21:19 +0300 Subject: [PATCH 22/90] Fix MaybeInaccessibleMessage --- .../Converters/MaybeInaccessibleMessageConverter.cs | 4 ++-- src/Telegram.Bot/Types/InaccessibleMessage.cs | 8 ++++---- src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs | 5 ----- src/Telegram.Bot/Types/Message.cs | 2 +- 4 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs b/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs index 29a6173b0..26508e1be 100644 --- a/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs +++ b/src/Telegram.Bot/Converters/MaybeInaccessibleMessageConverter.cs @@ -41,8 +41,8 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer var actualType = date switch { - 0 => typeof(Message), - _ => typeof(InaccessibleMessage), + 0 => typeof(InaccessibleMessage), + _ => typeof(Message), }; // Remove status because status property only has getter diff --git a/src/Telegram.Bot/Types/InaccessibleMessage.cs b/src/Telegram.Bot/Types/InaccessibleMessage.cs index 9945742f5..763a90f4e 100644 --- a/src/Telegram.Bot/Types/InaccessibleMessage.cs +++ b/src/Telegram.Bot/Types/InaccessibleMessage.cs @@ -4,23 +4,23 @@ namespace Telegram.Bot.Types; /// This object describes a message that was deleted or is otherwise inaccessible to the bot. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class InaccessibleMessage +public class InaccessibleMessage : MaybeInaccessibleMessage { /// /// Chat the message belonged to /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Unique message identifier inside the chat /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } = default!; + public int MessageId { get; set; } = default!; /// /// Always 0. The field can be used to differentiate regular and inaccessible messages. /// [JsonProperty(Required = Required.Always)] - public int Date { get; } = default!; + public int Date { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs index 84daadca4..93b14b2aa 100644 --- a/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs +++ b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs @@ -13,9 +13,4 @@ namespace Telegram.Bot.Types; [JsonConverter(typeof(MaybeInaccessibleMessageConverter))] public abstract class MaybeInaccessibleMessage { - /// - /// Date the message was sent. It is always a positive number, representing a valid date. - /// - [JsonProperty] - public abstract int Date { get; } } diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index 2ec511264..b3e1e28e3 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -12,7 +12,7 @@ namespace Telegram.Bot.Types; /// This object represents a message. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class Message +public class Message : MaybeInaccessibleMessage { /// /// Unique message identifier inside this chat From e447c0c25e5f0d547b24e38b81dbc78063bc9e95 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 05:23:39 +0300 Subject: [PATCH 23/90] Add setters to properties --- src/Telegram.Bot/Types/ChatBoost.cs | 8 ++++---- src/Telegram.Bot/Types/ChatBoostRemoved.cs | 8 ++++---- src/Telegram.Bot/Types/ChatBoostSource.cs | 6 +++--- src/Telegram.Bot/Types/ChatBoostUpdated.cs | 4 ++-- src/Telegram.Bot/Types/ExternalReplyInfo.cs | 2 +- src/Telegram.Bot/Types/Giveaway.cs | 6 +++--- src/Telegram.Bot/Types/GiveawayCompleted.cs | 2 +- src/Telegram.Bot/Types/GiveawayWinners.cs | 10 +++++----- src/Telegram.Bot/Types/MessageOrigin.cs | 20 +++++++++---------- .../Types/MessageReactionCountUpdated.cs | 8 ++++---- .../Types/MessageReactionUpdated.cs | 10 +++++----- src/Telegram.Bot/Types/ReactionCount.cs | 4 ++-- src/Telegram.Bot/Types/ReactionType.cs | 4 ++-- src/Telegram.Bot/Types/ReplyParameters.cs | 2 +- src/Telegram.Bot/Types/TextQuote.cs | 4 ++-- src/Telegram.Bot/Types/UserChatBoosts.cs | 2 +- 16 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/Telegram.Bot/Types/ChatBoost.cs b/src/Telegram.Bot/Types/ChatBoost.cs index a0c80f586..468238820 100644 --- a/src/Telegram.Bot/Types/ChatBoost.cs +++ b/src/Telegram.Bot/Types/ChatBoost.cs @@ -12,25 +12,25 @@ public class ChatBoost /// Unique identifier of the boost /// [JsonProperty(Required = Required.Always)] - public string BoostId { get; } = default!; + public string BoostId { get; set; } = default!; /// /// Point in time when the chat was boosted /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime AddDate { get; } = default!; + public DateTime AddDate { get; set; } = default!; /// /// Point in time when the boost will automatically expire, unless the booster's Telegram Premium subscription is prolonged /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime ExpirationDate { get; } = default!; + public DateTime ExpirationDate { get; set; } = default!; /// /// Source of the added boost /// [JsonProperty(Required = Required.Always)] - public ChatBoostSource Source { get; } = default!; + public ChatBoostSource Source { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ChatBoostRemoved.cs b/src/Telegram.Bot/Types/ChatBoostRemoved.cs index a82322f1a..1465cdaca 100644 --- a/src/Telegram.Bot/Types/ChatBoostRemoved.cs +++ b/src/Telegram.Bot/Types/ChatBoostRemoved.cs @@ -12,24 +12,24 @@ public class ChatBoostRemoved /// Chat which was boosted /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Unique identifier of the boost /// [JsonProperty(Required = Required.Always)] - public string BoostId { get; } = default!; + public string BoostId { get; set; } = default!; /// /// Point in time when the boost was removed /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime RemoveDate { get; } = default!; + public DateTime RemoveDate { get; set; } = default!; /// /// Source of the removed boost /// [JsonProperty(Required = Required.Always)] - public ChatBoostSource Source { get; } = default!; + public ChatBoostSource Source { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ChatBoostSource.cs b/src/Telegram.Bot/Types/ChatBoostSource.cs index 749073195..31d28cc7b 100644 --- a/src/Telegram.Bot/Types/ChatBoostSource.cs +++ b/src/Telegram.Bot/Types/ChatBoostSource.cs @@ -36,7 +36,7 @@ public abstract class ChatBoostSourcePremium : ChatBoostSource /// User that boosted the chat /// [JsonProperty(Required = Required.Always)] - public User User { get; } = default!; + public User User { get; set; } = default!; } /// @@ -55,7 +55,7 @@ public abstract class ChatBoostSourceGiftCode : ChatBoostSource /// User for which the gift code was created /// [JsonProperty(Required = Required.Always)] - public User User { get; } = default!; + public User User { get; set; } = default!; } /// @@ -75,7 +75,7 @@ public abstract class ChatBoostSourceGiveaway : ChatBoostSource /// May be 0 if the message isn't sent yet. /// [JsonProperty(Required = Required.Always)] - public int GiveawayMessageId { get; } = default!; + public int GiveawayMessageId { get; set; } = default!; /// /// Optional. User that won the prize in the giveaway if any diff --git a/src/Telegram.Bot/Types/ChatBoostUpdated.cs b/src/Telegram.Bot/Types/ChatBoostUpdated.cs index 6c950599c..b91889c3f 100644 --- a/src/Telegram.Bot/Types/ChatBoostUpdated.cs +++ b/src/Telegram.Bot/Types/ChatBoostUpdated.cs @@ -10,11 +10,11 @@ public class ChatBoostUpdated /// Chat which was boosted /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Information about the chat boost /// [JsonProperty(Required = Required.Always)] - public ChatBoost Boost { get; } = default!; + public ChatBoost Boost { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ExternalReplyInfo.cs b/src/Telegram.Bot/Types/ExternalReplyInfo.cs index 9dec272fa..52c915a0d 100644 --- a/src/Telegram.Bot/Types/ExternalReplyInfo.cs +++ b/src/Telegram.Bot/Types/ExternalReplyInfo.cs @@ -12,7 +12,7 @@ public class ExternalReplyInfo /// Origin of the message replied to by the given message /// [JsonProperty(Required = Required.Always)] - public MessageOrigin Origin { get; } = default!; + public MessageOrigin Origin { get; set; } = default!; /// /// Optional.Chat the original message belongs to.Available only if the chat is a supergroup or a channel. diff --git a/src/Telegram.Bot/Types/Giveaway.cs b/src/Telegram.Bot/Types/Giveaway.cs index 2983fc1ca..fc32f12be 100644 --- a/src/Telegram.Bot/Types/Giveaway.cs +++ b/src/Telegram.Bot/Types/Giveaway.cs @@ -12,20 +12,20 @@ public class Giveaway /// The list of chats which the user must join to participate in the giveaway /// [JsonProperty(Required = Required.Always)] - public Chat[] Chats { get; } = default!; + public Chat[] Chats { get; set; } = default!; /// /// Point in time when winners of the giveaway will be selected /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime WinnersSelectionDate { get; } = default!; + public DateTime WinnersSelectionDate { get; set; } = default!; /// /// The number of users which are supposed to be selected as winners of the giveaway /// [JsonProperty(Required = Required.Always)] - public int WinnerCount { get; } = default!; + public int WinnerCount { get; set; } = default!; /// /// Optional. , if only users who join the chats after the giveaway started should be eligible to win diff --git a/src/Telegram.Bot/Types/GiveawayCompleted.cs b/src/Telegram.Bot/Types/GiveawayCompleted.cs index 7f0ed4d8e..1f7fdd4e4 100644 --- a/src/Telegram.Bot/Types/GiveawayCompleted.cs +++ b/src/Telegram.Bot/Types/GiveawayCompleted.cs @@ -10,7 +10,7 @@ public class GiveawayCompleted /// Number of winners in the giveaway /// [JsonProperty(Required = Required.Always)] - public int WinnerCount { get; } = default!; + public int WinnerCount { get; set; } = default!; /// /// Optional. Number of undistributed prizes diff --git a/src/Telegram.Bot/Types/GiveawayWinners.cs b/src/Telegram.Bot/Types/GiveawayWinners.cs index 60e7f7fd0..b59cdc83d 100644 --- a/src/Telegram.Bot/Types/GiveawayWinners.cs +++ b/src/Telegram.Bot/Types/GiveawayWinners.cs @@ -12,32 +12,32 @@ public class GiveawayWinners /// The chat that created the giveaway /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Identifier of the message with the giveaway in the chat /// [JsonProperty(Required = Required.Always)] - public int GiveawayMessageId { get; } = default!; + public int GiveawayMessageId { get; set; } = default!; /// /// Point in time when winners of the giveaway were selected /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime WinnersSelectionDate { get; } = default!; + public DateTime WinnersSelectionDate { get; set; } = default!; /// /// Total number of winners in the giveaway /// [JsonProperty(Required = Required.Always)] - public int WinnerCount { get; } = default!; + public int WinnerCount { get; set; } = default!; /// /// List of up to 100 winners of the giveaway /// [JsonProperty(Required = Required.Always)] - public User[] Winners { get; } = default!; + public User[] Winners { get; set; } = default!; /// /// Optional. The number of other chats the user had to join in order to be eligible for the giveaway diff --git a/src/Telegram.Bot/Types/MessageOrigin.cs b/src/Telegram.Bot/Types/MessageOrigin.cs index dd02b5af5..b67322465 100644 --- a/src/Telegram.Bot/Types/MessageOrigin.cs +++ b/src/Telegram.Bot/Types/MessageOrigin.cs @@ -27,7 +27,7 @@ public abstract class MessageOrigin /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public abstract DateTime Date { get; } + public abstract DateTime Date { get; set; } } /// @@ -44,13 +44,13 @@ public class MessageOriginUser : MessageOrigin /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public override DateTime Date { get; } + public override DateTime Date { get; set; } /// /// User that sent the message originally /// [JsonProperty(Required = Required.Always)] - public User SenderUser { get; } = default!; + public User SenderUser { get; set; } = default!; } /// @@ -67,13 +67,13 @@ public class MessageOriginHiddenUser : MessageOrigin /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public override DateTime Date { get; } + public override DateTime Date { get; set; } /// /// Name of the user that sent the message originally /// [JsonProperty(Required = Required.Always)] - public string SenderUserName { get; } = default!; + public string SenderUserName { get; set; } = default!; } /// @@ -90,13 +90,13 @@ public class MessageOriginChat : MessageOrigin /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public override DateTime Date { get; } + public override DateTime Date { get; set; } /// /// Chat that sent the message originally /// [JsonProperty(Required = Required.Always)] - public Chat SenderChat { get; } = default!; + public Chat SenderChat { get; set; } = default!; /// /// Optional. For messages originally sent by an anonymous chat administrator, @@ -120,19 +120,19 @@ public class MessageOriginChannel : MessageOrigin /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public override DateTime Date { get; } + public override DateTime Date { get; set; } /// /// Channel chat to which the message was originally sent /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Unique message identifier inside the chat /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } = default!; + public int MessageId { get; set; } = default!; /// /// Optional. Signature of the original post author diff --git a/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs b/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs index 65fc21d8f..cc516ee1c 100644 --- a/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs +++ b/src/Telegram.Bot/Types/MessageReactionCountUpdated.cs @@ -12,24 +12,24 @@ public class MessageReactionCountUpdated /// The chat containing the message /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Unique message identifier inside the chat /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } = default!; + public int MessageId { get; set; } = default!; /// /// Date of the change /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime Date { get; } = default!; + public DateTime Date { get; set; } = default!; /// /// List of reactions that are present on the message /// [JsonProperty(Required = Required.Always)] - public ReactionCount[] Reactions { get; } = default!; + public ReactionCount[] Reactions { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/MessageReactionUpdated.cs b/src/Telegram.Bot/Types/MessageReactionUpdated.cs index 84db6082d..7c74d3420 100644 --- a/src/Telegram.Bot/Types/MessageReactionUpdated.cs +++ b/src/Telegram.Bot/Types/MessageReactionUpdated.cs @@ -12,13 +12,13 @@ public class MessageReactionUpdated /// The chat containing the message the user reacted to /// [JsonProperty(Required = Required.Always)] - public Chat Chat { get; } = default!; + public Chat Chat { get; set; } = default!; /// /// Unique identifier of the message inside the chat /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } = default!; + public int MessageId { get; set; } = default!; /// /// Optional.The user that changed the reaction, if the user isn't anonymous @@ -37,17 +37,17 @@ public class MessageReactionUpdated /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(UnixDateTimeConverter))] - public DateTime Date { get; } = default!; + public DateTime Date { get; set; } = default!; /// /// Previous list of reaction types that were set by the user /// [JsonProperty(Required = Required.Always)] - public ReactionType[] OldReaction { get; } = default!; + public ReactionType[] OldReaction { get; set; } = default!; /// /// New list of reaction types that have been set by the user /// [JsonProperty(Required = Required.Always)] - public ReactionType[] NewReaction { get; } = default!; + public ReactionType[] NewReaction { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ReactionCount.cs b/src/Telegram.Bot/Types/ReactionCount.cs index 50f2c1f8b..e0503a418 100644 --- a/src/Telegram.Bot/Types/ReactionCount.cs +++ b/src/Telegram.Bot/Types/ReactionCount.cs @@ -10,11 +10,11 @@ public class ReactionCount /// Type of the reaction /// [JsonProperty(Required = Required.Always)] - public ReactionType Type { get; } = default!; + public ReactionType Type { get; set; } = default!; /// /// Number of times the reaction was added /// [JsonProperty(Required = Required.Always)] - public int TotalCount { get; } = default!; + public int TotalCount { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ReactionType.cs b/src/Telegram.Bot/Types/ReactionType.cs index 571c15c0d..7cba3902c 100644 --- a/src/Telegram.Bot/Types/ReactionType.cs +++ b/src/Telegram.Bot/Types/ReactionType.cs @@ -40,7 +40,7 @@ public class ReactionTypeEmoji : ReactionType /// "💘", "🙉", "🦄", "😘", "💊", "🙊", "😎", "👾", "🤷‍♂", "🤷", "🤷‍♀", "😡" /// [JsonProperty(Required = Required.Always)] - public string Emoji { get; } = default!; + public string Emoji { get; set; } = default!; } /// @@ -58,5 +58,5 @@ public class ReactionTypeCustomEmoji : ReactionType /// Custom emoji identifier /// [JsonProperty(Required = Required.Always)] - public string CustomEmojiId { get; } = default!; + public string CustomEmojiId { get; set; } = default!; } diff --git a/src/Telegram.Bot/Types/ReplyParameters.cs b/src/Telegram.Bot/Types/ReplyParameters.cs index 0c763cce8..8c242f6ec 100644 --- a/src/Telegram.Bot/Types/ReplyParameters.cs +++ b/src/Telegram.Bot/Types/ReplyParameters.cs @@ -10,7 +10,7 @@ public class ReplyParameters /// Identifier of the message that will be replied to in the current chat, or in the chat if it is specified /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public int MessageId { get; set; } /// /// Optional. If the message to be replied to is from a different chat, unique identifier for the diff --git a/src/Telegram.Bot/Types/TextQuote.cs b/src/Telegram.Bot/Types/TextQuote.cs index fc3cba126..7f93050bd 100644 --- a/src/Telegram.Bot/Types/TextQuote.cs +++ b/src/Telegram.Bot/Types/TextQuote.cs @@ -10,7 +10,7 @@ public class TextQuote /// Text of the quoted part of a message that is replied to by the given message /// [JsonProperty(Required = Required.Always)] - public string Text { get; } = default!; + public string Text { get; set; } = default!; /// /// Optional. Special entities that appear in the quote. Currently, only bold, italic, underline, @@ -23,7 +23,7 @@ public class TextQuote /// Approximate quote position in the original message in UTF-16 code units as specified by the sender /// [JsonProperty(Required = Required.Always)] - public int Position { get; } = default!; + public int Position { get; set; } = default!; /// /// Optional.True, if the quote was chosen manually by the message sender.Otherwise, the quote was added automatically by the server. diff --git a/src/Telegram.Bot/Types/UserChatBoosts.cs b/src/Telegram.Bot/Types/UserChatBoosts.cs index 30323cf5a..b0bdeca54 100644 --- a/src/Telegram.Bot/Types/UserChatBoosts.cs +++ b/src/Telegram.Bot/Types/UserChatBoosts.cs @@ -12,5 +12,5 @@ public class UserChatBoosts /// The list of boosts added to the chat by the user /// [JsonProperty(Required = Required.Always)] - IEnumerable Boosts { get; } = default!; + IEnumerable Boosts { get; set; } = default!; } From 9a7bae6eba7b07857767f9f5a542a1749e5340e6 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Thu, 4 Jan 2024 05:38:36 +0300 Subject: [PATCH 24/90] Fix tests --- .../ChatMemberAdministrationTests.cs | 12 +++---- .../Exceptions/ApiExceptionsTests.cs | 24 +++++++------- .../Framework/TestsFixture.cs | 10 +++--- .../Framework/UpdateReceiver.cs | 10 +++--- .../Games/GamesExceptionTests.cs | 2 +- .../Other/BotCommandsTests.cs | 13 ++++++-- .../Other/BotDescriptionTests.cs | 13 ++++++-- .../Other/BotShortDescriptionTests.cs | 13 ++++++-- .../Sending Messages/AlbumMessageTests.cs | 20 ++++++------ .../Sending Messages/TextMessageTests.cs | 31 ++++++++----------- .../Stickers/StickersTests.cs | 16 +++++----- .../Stickers/StickersTestsFixture.cs | 2 +- 12 files changed, 91 insertions(+), 75 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs index df281d3ce..1c4164b8d 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs @@ -105,8 +105,8 @@ await BotClient.SendTextMessageAsync( predicate: u => u.Message!.Chat.Type == ChatType.Supergroup && u.Message!.Chat.Id == _fixture.SupergroupChat.Id - && u.Message!.Type == MessageType.ChatMembersAdded, - updateTypes: new[] { UpdateType.Message } + && u.Message!.Type == MessageType.NewChatMembers, + updateTypes: [UpdateType.Message] ); await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); @@ -295,7 +295,7 @@ await BotClient.SetChatAdministratorCustomTitleAsync( await BotClient.SetChatAdministratorCustomTitleAsync( chatId: _fixture.SupergroupChat, userId: promotedRegularUser.User.Id, - customTitle: string.Empty + customTitle: "" ); } @@ -371,8 +371,8 @@ await _fixture.SendTestInstructionsAsync( Assert.NotNull(chatMemberUpdated.OldChatMember); Assert.NotNull(chatMemberUpdated.NewChatMember); - Assert.True(chatMemberUpdated.OldChatMember.Status == ChatMemberStatus.Restricted); - Assert.True(chatMemberUpdated.NewChatMember.Status == ChatMemberStatus.Kicked); + Assert.Equal(ChatMemberStatus.Restricted, chatMemberUpdated.OldChatMember.Status); + Assert.Equal(ChatMemberStatus.Kicked, chatMemberUpdated.NewChatMember.Status); Assert.IsType(chatMemberUpdated.OldChatMember); ChatMemberBanned newChatMember = Assert.IsType(chatMemberUpdated.NewChatMember); @@ -398,7 +398,7 @@ await _fixture.SendTestInstructionsAsync( Update _ = await _fixture.UpdateReceiver .GetUpdateAsync( u => u.Message?.Chat.Id == _fixture.SupergroupChat.Id && - u.Message.Type == MessageType.ChatMembersAdded, + u.Message.Type == MessageType.NewChatMembers, updateTypes: UpdateType.Message, cancellationToken: cts.Token ); diff --git a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs index 5adef95c9..0ebf8cebe 100644 --- a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs @@ -21,32 +21,32 @@ public ApiExceptionsTests(TestsFixture fixture) _fixture = fixture; } - [OrderedFact("Should throw ChatNotInitiatedException while trying to send message to a user who hasn't " + + [OrderedFact("Should throw ChatNotFoundException while trying to send message to a user who hasn't " + "started a chat with bot but bot knows about him/her.")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] - public async Task Should_Throw_Exception_ChatNotInitiatedException() + public async Task Should_Throw_Exception_ChatNotFoundException() { //ToDo add exception. forward message from another bot. Forbidden: bot can't send messages to bots await _fixture.SendTestInstructionsAsync( "Forward a message to this chat from a user that never started a chat with this bot" ); - await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); + //await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); - Update forwardedMessageUpdate = await _fixture.UpdateReceiver.GetUpdateAsync( - predicate: u => u.Message?.ForwardFrom is not null, - updateTypes: new[] { UpdateType.Message } - ); + //Update forwardedMessageUpdate = await _fixture.UpdateReceiver.GetUpdateAsync( + // predicate: u => u.Message?.ForwardOrigin is not null, + // updateTypes: [UpdateType.Message] + //); - User forwardFromUser = forwardedMessageUpdate.Message!.ForwardFrom!; + //MessageOriginHiddenUser hiddenUser = (MessageOriginHiddenUser)forwardedMessageUpdate.Message!.ForwardOrigin; ApiRequestException e = await Assert.ThrowsAsync(async () => await BotClient.SendTextMessageAsync( - forwardFromUser.Id, - $"Error! If you see this message, talk to @{forwardFromUser.Username}" + int.MaxValue, + $"Error!" ) ); - Assert.Equal(403, e.ErrorCode); + Assert.Equal(400, e.ErrorCode); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs index 135afd2ee..0d8a832b7 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs @@ -118,7 +118,7 @@ bool IsMatch(Update u) => u.Message.Text?.StartsWith("/test", StringComparison.OrdinalIgnoreCase) == true ) || ( ChatType.Channel == chatType && - ChatType.Channel == u.Message?.ForwardFromChat?.Type + u.Message?.ForwardOrigin is MessageOriginChannel ); var updates = await UpdateReceiver.GetUpdatesAsync( @@ -132,7 +132,7 @@ bool IsMatch(Update u) => await UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); return chatType == ChatType.Channel - ? update.Message?.ForwardFromChat + ? ((MessageOriginChannel)update.Message?.ForwardOrigin).Chat : update.Message?.Chat; } @@ -143,7 +143,7 @@ static bool IsMatch(Update u) => u is Message: { Type: MessageType.Contact, - ForwardFrom: not null, + ForwardOrigin: not null, NewChatMembers.Length: > 0, } }; @@ -155,7 +155,7 @@ static bool IsMatch(Update u) => u is var userId = update.Message switch { { Contact.UserId: {} id } => id, - { ForwardFrom.Id: var id } => id, + { ForwardOrigin: MessageOriginUser originUser } => originUser.SenderUser.Id, { NewChatMembers: { Length: 1 } members } => members[0].Id, _ => throw new InvalidOperationException() }; @@ -259,7 +259,7 @@ async Task> FindAllowedTesterUserNames(CancellationToken can // Try to get user names from test configurations first var allowedUserNames = Configuration.AllowedUserNames; - if (allowedUserNames.Any()) return allowedUserNames; + if (allowedUserNames.Length != 0) return allowedUserNames; // Assume all chat admins are allowed testers var admins = await BotClient.GetChatAdministratorsAsync(SupergroupChat, cancellationToken); diff --git a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs index 5b41156f3..f849ad171 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs @@ -26,7 +26,7 @@ public class UpdateReceiver public UpdateReceiver(ITelegramBotClient botClient, IEnumerable? allowedUsernames) { _botClient = botClient; - AllowedUsernames = allowedUsernames?.ToList() ?? new(); + AllowedUsernames = allowedUsernames?.ToList() ?? []; } public async Task DiscardNewUpdatesAsync(CancellationToken cancellationToken = default) @@ -79,7 +79,7 @@ public async Task GetUpdatesAsync( cancellationToken = cts.Token; } - Update[] matchingUpdates = Array.Empty(); + Update[] matchingUpdates = []; while (!cancellationToken.IsCancellationRequested) { @@ -143,7 +143,7 @@ public async Task GetCallbackQueryUpdateAsync( if (discardNewUpdates) { await DiscardNewUpdatesAsync(cancellationToken); } var updates = await GetUpdatesAsync( - predicate: u => (messageId is null || u.CallbackQuery?.Message?.MessageId == messageId) && + predicate: u => (messageId is null || ((Message?)u.CallbackQuery?.Message)?.MessageId == messageId) && (data is null || u.CallbackQuery?.Data == data), updateTypes: new [] { UpdateType.CallbackQuery }, cancellationToken: cancellationToken @@ -161,7 +161,7 @@ public async Task GetInlineQueryUpdateAsync( if (discardNewUpdates) { await DiscardNewUpdatesAsync(cancellationToken); } var updates = await GetUpdatesAsync( - updateTypes: new [] { UpdateType.InlineQuery }, + updateTypes: [UpdateType.InlineQuery], cancellationToken: cancellationToken ); @@ -194,7 +194,7 @@ public async Task GetInlineQueryUpdateAsync( id == chatId && type == messageType) || u.ChosenInlineResult is not null, cancellationToken: cancellationToken, - updateTypes: new[] { UpdateType.Message, UpdateType.ChosenInlineResult } + updateTypes: [UpdateType.Message, UpdateType.ChosenInlineResult] ); messageUpdate = updates.SingleOrDefault(u => u.Message?.Type == messageType); diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs index fe127fa0f..c2c2b37f6 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs @@ -39,7 +39,7 @@ public async Task Should_Throw_InvalidGameShortNameException_2() ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.SendGameAsync( chatId: _fixture.SupergroupChat.Id, - gameShortName: string.Empty + gameShortName: "" ) ); diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs index 9a67bfe01..963ad0671 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; @@ -50,7 +51,7 @@ await BotClient.SetMyCommandsAsync( public async Task Should_Get_Set_Bot_Commands() { BotCommand[] commands = - { + [ new() { Command = "start", @@ -61,7 +62,7 @@ public async Task Should_Get_Set_Bot_Commands() Command = "help", Description = "Help command" }, - }; + ]; _scope = BotCommandScope.Default(); @@ -70,6 +71,8 @@ await _fixture.BotClient.SetMyCommandsAsync( scope: _scope ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotCommand[] currentCommands = await _fixture.BotClient.GetMyCommandsAsync(); Assert.Equal(2, currentCommands.Length); @@ -102,6 +105,8 @@ await BotClient.SetMyCommandsAsync( scope: _scope ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotCommand[] setCommands = await BotClient.GetMyCommandsAsync(); Assert.NotNull(setCommands); @@ -140,6 +145,8 @@ await BotClient.SetMyCommandsAsync( scope: _scope ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotCommand[] newCommands = await BotClient.GetMyCommandsAsync(scope: _scope); Asserts.JsonEquals(commands, newCommands); @@ -147,4 +154,4 @@ await BotClient.SetMyCommandsAsync( public Task InitializeAsync() => Task.CompletedTask; public async Task DisposeAsync() => await _fixture.BotClient.DeleteMyCommandsAsync(scope: _scope); -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs index b8de14c42..69de8c442 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; @@ -40,6 +41,8 @@ await BotClient.SetMyDescriptionAsync( description: description ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotDescription currentDescription = await _fixture.BotClient.GetMyDescriptionAsync(); Assert.NotNull(currentDescription); @@ -62,9 +65,11 @@ await BotClient.SetMyDescriptionAsync( Assert.Equal(description, setDescription.Description); await BotClient.SetMyDescriptionAsync( - description: string.Empty + description: "" ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotDescription currentDescription = await _fixture.BotClient.GetMyDescriptionAsync(); Assert.NotNull(currentDescription.Description); @@ -84,6 +89,8 @@ await BotClient.SetMyDescriptionAsync( languageCode: _languageCode ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotDescription newDescription = await _fixture.BotClient.GetMyDescriptionAsync(languageCode: _languageCode); Assert.NotNull(newDescription); @@ -95,11 +102,11 @@ await BotClient.SetMyDescriptionAsync( public async Task DisposeAsync() { await BotClient.SetMyDescriptionAsync( - description: string.Empty + description: "" ); await BotClient.SetMyDescriptionAsync( - description: string.Empty, + description: "", languageCode: _languageCode ); } diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs index daa1eafa8..98e491be3 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs @@ -1,3 +1,4 @@ +using System; using System.Threading.Tasks; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; @@ -40,6 +41,8 @@ await BotClient.SetMyShortDescriptionAsync( shortDescription: shortDescription ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotShortDescription currentShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); Assert.NotNull(currentShortDescription); @@ -62,9 +65,11 @@ await BotClient.SetMyShortDescriptionAsync( Assert.Equal(shortDescription, setShortDescription.ShortDescription); await BotClient.SetMyShortDescriptionAsync( - shortDescription: string.Empty + shortDescription: "" ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotShortDescription currentShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); Assert.NotNull(currentShortDescription.ShortDescription); @@ -84,6 +89,8 @@ await BotClient.SetMyShortDescriptionAsync( languageCode: _languageCode ); + await Task.Delay(TimeSpan.FromSeconds(10)); + BotShortDescription newDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(languageCode: _languageCode); Assert.NotNull(newDescription); @@ -95,11 +102,11 @@ await BotClient.SetMyShortDescriptionAsync( public async Task DisposeAsync() { await BotClient.SetMyShortDescriptionAsync( - shortDescription: string.Empty + shortDescription: "" ); await BotClient.SetMyShortDescriptionAsync( - shortDescription: string.Empty, + shortDescription: "", languageCode: _languageCode ); } diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs index 8bdfce4b7..d90a609fd 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs @@ -36,7 +36,7 @@ public async Task Should_Upload_2_Photos_Album() ) { IAlbumInputMedia[] inputMedia = - { + [ new InputMediaPhoto(new InputFileStream(stream1, "logo.png")) { Caption = "Logo" @@ -45,7 +45,7 @@ public async Task Should_Upload_2_Photos_Album() { Caption = "Bot" }, - }; + ]; messages = await BotClient.SendMediaGroupAsync( chatId: _fixture.SupergroupChat.Id, @@ -59,7 +59,7 @@ public async Task Should_Upload_2_Photos_Album() // All media messages have the same mediaGroupId Assert.NotEmpty(messages.Select(m => m.MediaGroupId)); - Assert.True(messages.Select(msg => msg.MediaGroupId).Distinct().Count() == 1); + Assert.Single(messages.Select(msg => msg.MediaGroupId).Distinct()); Assert.Equal("Logo", messages[0].Caption); Assert.Equal("Bot", messages[1].Caption); @@ -104,7 +104,7 @@ public async Task Should_Send_Photo_Album_Using_Url() new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/06/20/19/22/fuchs-2424369_640.jpg")), new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")), }, - replyToMessageId: replyToMessageId + replyParameters: new() { MessageId = replyToMessageId } ); Assert.Equal(2, messages.Length); @@ -129,7 +129,7 @@ public async Task Should_Upload_2_Videos_Album() ) { IAlbumInputMedia[] inputMedia = - { + [ new InputMediaVideo(new InputFileStream(stream0, "GoldenRatio.mp4")) { Caption = "Golden Ratio", @@ -145,7 +145,7 @@ public async Task Should_Upload_2_Videos_Album() { Caption = "Bot" }, - }; + ]; messages = await BotClient.SendMediaGroupAsync( chatId: _fixture.SupergroupChat.Id, @@ -185,7 +185,7 @@ public async Task Should_Upload_2_Photos_Album_With_Markdown_Encoded_Captions() stream2 = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot); IAlbumInputMedia[] inputMedia = - { + [ new InputMediaPhoto(new InputFileStream(stream1, "logo.png")) { Caption = "*Logo*", @@ -196,7 +196,7 @@ public async Task Should_Upload_2_Photos_Album_With_Markdown_Encoded_Captions() Caption = "_Bot_", ParseMode = ParseMode.Markdown }, - }; + ]; Message[] messages = await BotClient.SendMediaGroupAsync( chatId: _fixture.SupergroupChat.Id, @@ -228,14 +228,14 @@ public async Task Should_Video_With_Thumbnail_In_Album() stream2 = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); IAlbumInputMedia[] inputMedia = - { + [ new InputMediaVideo(new InputFileStream(stream1, "GoldenRatio.mp4")) { Thumbnail = new InputFileStream(stream2, "thumbnail.jpg"), SupportsStreaming = true, }, new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")), - }; + ]; Message[] messages = await BotClient.SendMediaGroupAsync( chatId: _fixture.SupergroupChat.Id, diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs index 0d35230d5..dbea109b9 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs @@ -80,13 +80,11 @@ public async Task Should_Forward_Message() messageId: message1.MessageId ); - Asserts.UsersEqual(_fixture.BotUser, message2.ForwardFrom); - Assert.Null(message2.ForwardFromChat); - Assert.Equal(default, message2.ForwardFromMessageId); - Assert.Null(message2.ForwardSignature); - Assert.NotNull(message2.ForwardDate); + MessageOriginUser forwardOrigin = (MessageOriginUser)message2.ForwardOrigin; + Assert.NotNull(forwardOrigin); + Asserts.UsersEqual(_fixture.BotUser, forwardOrigin.SenderUser); Assert.InRange( - message2.ForwardDate.Value, + forwardOrigin.Date, DateTime.UtcNow.AddSeconds(-20), DateTime.UtcNow ); @@ -115,7 +113,7 @@ public async Task Should_Parse_MarkDown_Entities() chatId: _fixture.SupergroupChat.Id, text: string.Join("\n", entityValueMappings.Values), parseMode: ParseMode.Markdown, - disableWebPagePreview: true + linkPreviewOptions: new() { IsDisabled = true } ); Assert.NotNull(message.Entities); @@ -133,7 +131,7 @@ public async Task Should_Parse_HTML_Entities() { const string url = "https://telegram.org/"; (MessageEntityType Type, string Value)[] entityValueMappings = - { + [ (MessageEntityType.Bold, "bold"), (MessageEntityType.Bold, "<strong>"), (MessageEntityType.Italic, "italic"), @@ -148,13 +146,13 @@ public async Task Should_Parse_HTML_Entities() (MessageEntityType.Strikethrough, "strikethrough"), (MessageEntityType.Underline, "underline"), (MessageEntityType.Spoiler, "spoiler"), - }; + ]; Message message = await BotClient.SendTextMessageAsync( chatId: _fixture.SupergroupChat.Id, text: string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)), parseMode: ParseMode.Html, - disableWebPagePreview: true + linkPreviewOptions: new() { IsDisabled = true } ); Assert.NotNull(message.Entities); @@ -174,7 +172,7 @@ public async Task Should_Parse_HTML_Entities() public async Task Should_Parse_Message_Entities_Into_Values() { (MessageEntityType Type, string Value)[] entityValueMappings = - { + [ (MessageEntityType.PhoneNumber, "+38612345678"), (MessageEntityType.Cashtag, "$EUR"), (MessageEntityType.Hashtag, "#TelegramBots"), @@ -183,7 +181,7 @@ public async Task Should_Parse_Message_Entities_Into_Values() (MessageEntityType.Email, "security@telegram.org"), (MessageEntityType.BotCommand, "/test"), (MessageEntityType.BotCommand, $"/test@{_fixture.BotUser.Username}"), - }; + ]; Message message = await BotClient.SendTextMessageAsync( chatId: _fixture.SupergroupChat.Id, @@ -224,7 +222,7 @@ public async Task Should_Parse_MarkdownV2_Entities() chatId: _fixture.SupergroupChat.Id, text: string.Join("\n", entityValueMappings.Values), parseMode: ParseMode.MarkdownV2, - disableWebPagePreview: true + linkPreviewOptions: new() { IsDisabled = true } ); Assert.NotNull(message.Entities); @@ -282,10 +280,7 @@ public async Task Should_Receive_Error_Trying_Forward_A_Message__With_Protected_ Assert.Equal(400, exception.ErrorCode); } - public class Fixture : ChannelChatFixture + public class Fixture(TestsFixture testsFixture) : ChannelChatFixture(testsFixture, Constants.TestCollections.SendTextMessage) { - public Fixture(TestsFixture testsFixture) - : base(testsFixture, Constants.TestCollections.SendTextMessage) - { } } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs index 7ec728bab..fde87771c 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs @@ -235,7 +235,7 @@ public async Task Should_Send_Static_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join(string.Empty, _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -276,7 +276,7 @@ public async Task Should_Send_Animated_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join(string.Empty, _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -317,7 +317,7 @@ public async Task Should_Send_Video_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join(string.Empty, _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -377,7 +377,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join(string.Empty, _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -416,7 +416,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join(string.Empty, _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.True(thirdSticker.IsAnimated); @@ -455,7 +455,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join(string.Empty, _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -530,7 +530,7 @@ public async Task Should_Set_First_Sticker_EmojiList() Sticker firstSticker = stickerSet.Stickers.First(); - string thirdEmojisString = string.Join(string.Empty, _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, firstSticker.Emoji); @@ -547,7 +547,7 @@ await BotClient.SetStickerEmojiListAsync( Sticker updatedFirstSticker = updatedStickerSet.Stickers.First(); - string firstEmojisString = string.Join(string.Empty, _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, updatedFirstSticker.Emoji); } diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs index 0b2053569..d2ae50cce 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs @@ -89,7 +89,7 @@ static async Task GetStickerOwnerIdAsync(TestsFixture testsFixture, string testsFixture.SupergroupChat, testsFixture.UpdateReceiver.GetTesters() + "\nUse the following button to become Sticker Set Owner", - replyToMessageId: notificationMessage.MessageId, + replyParameters: new() { MessageId = notificationMessage.MessageId }, replyMarkup: new InlineKeyboardMarkup( InlineKeyboardButton.WithCallbackData("I am the Owner!", cqData) ) From b74ba09dc3c78971381d238f4664020914947a79 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:09:43 +0300 Subject: [PATCH 25/90] Reactions: add KnownReactionTypeEmoji --- CHANGELOG.md | 1 + .../Types/Enums/KnownReactionTypeEmoji.cs | 300 ++++++++++++++++++ src/Telegram.Bot/Types/ReactionType.cs | 3 + 3 files changed, 304 insertions(+) create mode 100644 src/Telegram.Bot/Types/Enums/KnownReactionTypeEmoji.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 324965081..0763765c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ### Added - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. +- The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. - Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. - Updates about reaction changes on a message with anonymous reactions, represented by the class `MessageReactionCountUpdated` diff --git a/src/Telegram.Bot/Types/Enums/KnownReactionTypeEmoji.cs b/src/Telegram.Bot/Types/Enums/KnownReactionTypeEmoji.cs new file mode 100644 index 000000000..3725afaf1 --- /dev/null +++ b/src/Telegram.Bot/Types/Enums/KnownReactionTypeEmoji.cs @@ -0,0 +1,300 @@ +namespace Telegram.Bot.Types.Enums; + +/// +/// Reaction emoji. +/// +public static class KnownReactionTypeEmoji +{ + /// + /// Thumbs Up Emoji + /// + public const string ThumbsUp = "👍"; + /// + /// Thumbs Down Emoji + /// + public const string ThumbsDown = "👎"; + /// + /// Red Heart Emoji + /// + public const string RedHeart = "❤"; + /// + /// Fire Emoji + /// + public const string Fire = "🔥"; + /// + /// Smiling Face with Hearts Emoji + /// + public const string SmilingFaceWithHearts = "🥰"; + /// + /// Clapping Hands Emoji + /// + public const string ClappingHands = "👏"; + /// + /// Beaming Face with Smiling Eyes Emoji + /// + public const string BeamingFaceWithSmilingEyes = "😁"; + /// + /// Thinking Face Emoji + /// + public const string ThinkingFace = "🤔"; + /// + /// Exploding Head Emoji + /// + public const string ExplodingHead = "🤯"; + /// + /// Face Screaming in Fear Emoji + /// + public const string FaceScreamingInFear = "😱"; + /// + /// Face with Symbols on Mouth Emoji + /// + public const string FaceWithSymbolsOnMouth = "🤬"; + /// + /// Crying Face Emoji + /// + public const string CryingFace = "😢"; + /// + /// Party Popper Emoji + /// + public const string PartyPopper = "🎉"; + /// + /// Star-Struck Emoji + /// + public const string StarStruck = "🤩"; + /// + /// Face Vomiting Emoji + /// + public const string FaceVomiting = "🤮"; + /// + /// Pile of Poo Emoji + /// + public const string PileOfPoo = "💩"; + /// + /// Folded Hands Emoji + /// + public const string FoldedHands = "🙏"; + /// + /// OK Hand Emoji + /// + public const string OKHand = "👌"; + /// + /// Dove Emoji + /// + public const string Dove = "🕊"; + /// + /// Clown Face Emoji + /// + public const string ClownFace = "🤡"; + /// + /// Yawning Face Emoji + /// + public const string YawningFace = "🥱"; + /// + /// Woozy Face Emoji + /// + public const string WoozyFace = "🥴"; + /// + /// Smiling Face with Heart-Eyes Emoji + /// + public const string SmilingFaceWithHeartEyes = "😍"; + /// + /// Spouting Whale Emoji + /// + public const string SpoutingWhale = "🐳"; + /// + /// Heart on Fire Emoji + /// + public const string HeartOnFire = "❤‍🔥"; + /// + /// New Moon Face Emoji + /// + public const string NewMoonFace = "🌚"; + /// + /// Hot Dog Emoji + /// + public const string HotDog = "🌭"; + /// + /// Hundred Points Emoji + /// + public const string HundredPoints = "💯"; + /// + /// Rolling on the Floor Laughing Emoji + /// + public const string RollingOnTheFloorLaughing = "🤣"; + /// + /// High Voltage Emoji + /// + public const string HighVoltage = "⚡"; + /// + /// Banana Emoji + /// + public const string Banana = "🍌"; + /// + /// Trophy Emoji + /// + public const string Trophy = "🏆"; + /// + /// Broken Heart Emoji + /// + public const string BrokenHeart = "💔"; + /// + /// Face with Raised Eyebrow Emoji + /// + public const string FaceWithRaisedEyebrow = "🤨"; + /// + /// Neutral Face Emoji + /// + public const string NeutralFace = "😐"; + /// + /// Strawberry Emoji + /// + public const string Strawberry = "🍓"; + /// + /// Bottle with Popping Cork Emoji + /// + public const string BottleWithPoppingCork = "🍾"; + /// + /// Kiss Mark Emoji + /// + public const string KissMark = "💋"; + /// + /// Middle Finger Emoji + /// + public const string MiddleFinger = "🖕"; + /// + /// Smiling Face with Horns Emoji + /// + public const string SmilingFaceWithHorns = "😈"; + /// + /// Sleeping Face Emoji + /// + public const string SleepingFace = "😴"; + /// + /// Loudly Crying Face Emoji + /// + public const string LoudlyCryingFace = "😭"; + /// + /// Nerd Face Emoji + /// + public const string NerdFace = "🤓"; + /// + /// Ghost Emoji + /// + public const string Ghost = "👻"; + /// + /// Man Technologist Emoji + /// + public const string ManTechnologist = "👨‍💻"; + /// + /// Eyes Emoji + /// + public const string Eyes = "👀"; + /// + /// Jack-O-Lantern Emoji + /// + public const string JackOLantern = "🎃"; + /// + /// See-No-Evil Monkey Emoji + /// + public const string SeeNoEvilMonkey = "🙈"; + /// + /// Smiling Face with Halo Emoji + /// + public const string SmilingFaceWithHalo = "😇"; + /// + /// Fearful Face Emoji + /// + public const string FearfulFace = "😨"; + /// + /// Handshake Emoji + /// + public const string Handshake = "🤝"; + /// + /// Writing Hand Emoji + /// + public const string WritingHand = "✍"; + /// + /// Smiling Face with Open Hands Emoji + /// + public const string SmilingFaceWithOpenHands = "🤗"; + /// + /// Saluting Face Emoji + /// + public const string SalutingFace = "🫡"; + /// + /// Santa Claus Emoji + /// + public const string SantaClaus = "🎅"; + /// + /// Christmas Tree Emoji + /// + public const string ChristmasTree = "🎄"; + /// + /// Snowman Emoji + /// + public const string Snowman = "☃"; + /// + /// Nail Polish Emoji + /// + public const string NailPolish = "💅"; + /// + /// Zany Face Emoji + /// + public const string ZanyFace = "🤪"; + /// + /// Moai Emoji + /// + public const string Moai = "🗿"; + /// + /// Cool Button Emoji + /// + public const string CoolButton = "🆒"; + /// + /// Heart with Arrow Emoji + /// + public const string HeartWithArrow = "💘"; + /// + /// Hear-No-Evil Monkey Emoji + /// + public const string HearNoEvilMonkey = "🙉"; + /// + /// Unicorn Emoji + /// + public const string Unicorn = "🦄"; + /// + /// Face Blowing a Kiss Emoji + /// + public const string FaceBlowingAKiss = "😘"; + /// + /// Pill Emoji + /// + public const string Pill = "💊"; + /// + /// Speak-No-Evil Monkey Emoji + /// + public const string SpeakNoEvilMonkey = "🙊"; + /// + /// Smiling Face with Sunglasses Emoji + /// + public const string SmilingFaceWithSunglasses = "😎"; + /// + /// Alien Monster Emoji + /// + public const string AlienMonster = "👾"; + /// + /// Man Shrugging Emoji + /// + public const string ManShrugging = "🤷‍♂"; + /// + /// Shrugging Person Emoji + /// + public const string ShruggingPerson = "🤷"; + /// + /// Woman Shrugging Emoji + /// + public const string WomanShrugging = "🤷‍♀"; + /// + /// Enraged Face Emoji + /// + public const string EnragedFace = "😡"; +} diff --git a/src/Telegram.Bot/Types/ReactionType.cs b/src/Telegram.Bot/Types/ReactionType.cs index 7cba3902c..396ede22e 100644 --- a/src/Telegram.Bot/Types/ReactionType.cs +++ b/src/Telegram.Bot/Types/ReactionType.cs @@ -39,6 +39,9 @@ public class ReactionTypeEmoji : ReactionType /// "🙈", "😇", "😨", "🤝", "✍", "🤗", "🫡", "🎅", "🎄", "☃", "💅", "🤪", "🗿", "🆒", /// "💘", "🙉", "🦄", "😘", "💊", "🙊", "😎", "👾", "🤷‍♂", "🤷", "🤷‍♀", "😡" /// + /// + /// Available shortcuts: + /// [JsonProperty(Required = Required.Always)] public string Emoji { get; set; } = default!; } From 92972eb610dd18482e76a9e096eb773aba0f6509 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:21:20 +0300 Subject: [PATCH 26/90] Fix SendVideoMessage tests --- .../Sending Messages/VideoMessageTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs index 5a389a1de..499e2d733 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs @@ -42,7 +42,7 @@ public async Task Should_Send_Video() Assert.NotNull(message.Video); Assert.NotEmpty(message.Video.FileId); Assert.NotEmpty(message.Video.FileUniqueId); - Assert.Equal(104, message.Video.Duration); + Assert.True(message.Video.Duration >= 104); Assert.Equal(320, message.Video.Width); Assert.Equal(240, message.Video.Height); Assert.Equal("video/mp4", message.Video.MimeType); @@ -76,7 +76,7 @@ public async Task Should_Send_Video_Note() Assert.NotNull(message.VideoNote); Assert.NotEmpty(message.VideoNote.FileId); Assert.NotEmpty(message.VideoNote.FileUniqueId); - Assert.Equal(28, message.VideoNote.Duration); + Assert.True(message.VideoNote.Duration >= 28); Assert.Equal(240, message.VideoNote.Length); Assert.NotNull(message.VideoNote.Thumbnail); Assert.NotEmpty(message.VideoNote.Thumbnail.FileId); From 806f2cd6db9c9ce4eafdc1f8e1828e7958589d24 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:21:54 +0300 Subject: [PATCH 27/90] Bump xUnit in test projects --- test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj | 4 ++-- test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj index 48939b163..429e970f6 100644 --- a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj +++ b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj @@ -16,8 +16,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj index 8704c7887..02d46eba5 100644 --- a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj +++ b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj @@ -7,8 +7,8 @@ - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive From b12fce61413947d5f9f9c4e51996900d65f69787 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:28:24 +0300 Subject: [PATCH 28/90] Fix bug #1336 --- src/Telegram.Bot/Extensions/HttpContentExtensions.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Telegram.Bot/Extensions/HttpContentExtensions.cs b/src/Telegram.Bot/Extensions/HttpContentExtensions.cs index 7d043cd71..6476c8365 100644 --- a/src/Telegram.Bot/Extensions/HttpContentExtensions.cs +++ b/src/Telegram.Bot/Extensions/HttpContentExtensions.cs @@ -21,6 +21,7 @@ internal static MultipartFormDataContent AddContentIfInputFile( // It will be dispose of after the request is made #pragma warning disable CA2000 + inputFile.Content.Position = 0; var mediaPartContent = new StreamContent(inputFile.Content) { Headers = From 6b58640509b617c542885e2d948707a7366e9a46 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 17:33:21 +0300 Subject: [PATCH 29/90] Fix SetChatPermissionsAsync test --- .../Admin Bot/SupergroupAdminBotTests.cs | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs index 36c6ac9d5..bca714729 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs @@ -45,17 +45,24 @@ public async Task Should_Set_New_Default_Permissions() { ChatPermissions newDefaultPermissions = new() { - CanInviteUsers = false, - CanSendVoiceNotes = true, - CanChangeInfo = false, CanSendMessages = true, - CanPinMessages = false, - CanSendPolls = false, - CanSendOtherMessages = false, - CanAddWebPagePreviews = false + CanSendAudios=false, + CanSendDocuments=true, + CanSendPhotos=false, + CanSendVideos=false, + CanSendVideoNotes=false, + CanSendVoiceNotes=true, + CanSendPolls=false, + CanSendOtherMessages=false, + CanAddWebPagePreviews=false, + CanChangeInfo=false, + CanInviteUsers=false, + CanPinMessages=false, + CanManageTopics=false, }; await BotClient.SetChatPermissionsAsync(_classFixture.Chat.Id, newDefaultPermissions); + Chat supergroup = await BotClient.GetChatAsync(_classFixture.Chat.Id); ChatPermissions setChatPermissions = supergroup.Permissions!; @@ -259,10 +266,9 @@ public async Task Should_Create_Chat_Invite_Link() ChatInviteLink chatInviteLink = await BotClient.CreateChatInviteLinkAsync( chatId: _classFixture.TestsFixture.SupergroupChat.Id, - createsJoinRequest: true, name: inviteLinkName, - expireDate: expireDate - ); + expireDate: expireDate, + createsJoinRequest: true); Assert.NotNull(chatInviteLink); Assert.NotNull(chatInviteLink.Creator); @@ -297,10 +303,10 @@ public async Task Should_Edit_Chat_Invite_Link() ChatInviteLink editedChatInviteLink = await BotClient.EditChatInviteLinkAsync( chatId: _classFixture.TestsFixture.SupergroupChat.Id, inviteLink: _classFixture.ChatInviteLink.InviteLink, - createsJoinRequest: false, name: inviteLinkName, expireDate: expireDate, - memberLimit: 100 + memberLimit: 100, + createsJoinRequest: false ); ChatInviteLink chatInviteLink = _classFixture.ChatInviteLink; From b15a7df3d32531cb0d463ac9649b9d8ecae0aa81 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Fri, 5 Jan 2024 17:34:14 +0300 Subject: [PATCH 30/90] Fix public class ReplyMarkupSerializationTests warning --- .../Serialization/ReplyMarkupSerializationTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs index 17169002b..9d8001129 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs @@ -10,7 +10,7 @@ public class ReplyMarkupSerializationTests [InlineData(null)] [InlineData("regular")] [InlineData("quiz")] - public void Should_Serialize_Request_Poll_Keyboard_Button(string type) + public void Should_Serialize_Request_Poll_Keyboard_Button(string? type) { IReplyMarkup replyMarkup = new ReplyKeyboardMarkup( KeyboardButton.WithRequestPoll("Create a poll", type) From bda138cf916149d92e5d32ca0dc503bf0cae1e1e Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Sat, 6 Jan 2024 02:15:22 +0300 Subject: [PATCH 31/90] Add constructor for button mandatory parameters --- .../Types/ReplyMarkups/KeyboardButton.cs | 45 ++++++++++++++++--- .../ReplyMarkups/KeyboardButtonRequestChat.cs | 26 ++++++++--- .../KeyboardButtonRequestUsers.cs | 14 +++++- src/Telegram.Bot/Types/WebAppInfo.cs | 16 ++++++- 4 files changed, 88 insertions(+), 13 deletions(-) diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs index 5c3f7957c..b56deff52 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs @@ -91,29 +91,64 @@ public static KeyboardButton WithRequestPoll(string text, string? type = default /// Generate a keyboard button to request a web app /// /// Button's text - /// Web app information + /// + /// An HTTPS URL of a Web App to be opened with additional data as specified in + /// Initializing Web Apps + /// /// + public static KeyboardButton WithWebApp(string text, string url) => + new(text) { WebApp = new(url) }; + + /// + /// Generate a keyboard button to request a web app + /// + /// Button's text + /// Web app information public static KeyboardButton WithWebApp(string text, WebAppInfo webAppInfo) => new(text) { WebApp = webAppInfo }; /// - /// Generate a keyboard button to request user info + /// Generate a keyboard button to request users /// /// Button's text /// Criteria used to request a suitable users /// - public static KeyboardButton WithRequestUser(string text, KeyboardButtonRequestUsers requestUsers) => + public static KeyboardButton WithRequestUsers(string text, KeyboardButtonRequestUsers requestUsers) => new(text) { RequestUsers = requestUsers }; /// - /// Generate a keyboard button to request chat info + /// Generate a keyboard button to request users + /// + /// Button's text + /// + /// Signed 32-bit identifier of the request that will be received back in the object. + /// Must be unique within the message + /// + public static KeyboardButton WithRequestUsers(string text, int requestId) => + new(text) { RequestUsers = new(requestId) }; + + /// + /// Generate a keyboard button to request a chat /// /// Button's text /// Criteria used to request a suitable chat - /// public static KeyboardButton WithRequestChat(string text, KeyboardButtonRequestChat requestChat) => new(text) { RequestChat = requestChat }; + /// + /// Generate a keyboard button to request a chat + /// + /// Button's text + /// + /// Signed 32-bit identifier of the request, which will be received back in the object. + /// Must be unique within the message + /// + /// + /// Pass to request a channel chat, pass to request a group or a supergroup chat. + /// + public static KeyboardButton WithRequestChat(string text, int requestId, bool chatIsChannel) => + new(text) { RequestChat = new(requestId, chatIsChannel) }; + /// /// Generate a keyboard button from text /// diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs index b551c0a6b..5d13715fe 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs @@ -8,17 +8,17 @@ namespace Telegram.Bot.Types.ReplyMarkups; public class KeyboardButtonRequestChat { /// - /// Signed 32-bit identifier of the request + /// Signed 32-bit identifier of the request, which will be received back in the object. + /// Must be unique within the message /// [JsonProperty(Required = Required.Always)] - public int RequestId { get; set; } + public int RequestId { get; } /// - /// Pass to request a channel chat, pass to request a group - /// or a supergroup chat. + /// Pass to request a channel chat, pass to request a group or a supergroup chat. /// [JsonProperty(Required = Required.Always)] - public bool ChatIsChannel { get; set; } + public bool ChatIsChannel { get; } /// /// Optional. Pass to request a forum supergroup, pass to @@ -63,4 +63,20 @@ public class KeyboardButtonRequestChat /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool BotIsMember { get; set; } + + /// + /// Initializes a new instance of the class with requestId and chatIsChannel + /// + /// + /// Signed 32-bit identifier of the request, which will be received back in the object. + /// Must be unique within the message + /// + /// + /// Pass to request a channel chat, pass to request a group or a supergroup chat. + /// + public KeyboardButtonRequestChat(int requestId, bool chatIsChannel) + { + RequestId = requestId; + ChatIsChannel = chatIsChannel; + } } diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs index 9629516d9..ac03ca0d4 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs @@ -12,7 +12,7 @@ public class KeyboardButtonRequestUsers /// Must be unique within the message /// [JsonProperty(Required = Required.Always)] - public int RequestId { get; set; } + public int RequestId { get; } /// /// Optional. Pass to request bots, pass to request regular users. @@ -33,4 +33,16 @@ public class KeyboardButtonRequestUsers /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public int? MaxQuantity { get; set; } + + /// + /// Initializes a new instance of the class with requestId + /// + /// + /// Signed 32-bit identifier of the request that will be received back in the object. + /// Must be unique within the message + /// + public KeyboardButtonRequestUsers(int requestId) + { + RequestId = requestId; + } } diff --git a/src/Telegram.Bot/Types/WebAppInfo.cs b/src/Telegram.Bot/Types/WebAppInfo.cs index abefa49f4..766a4bc92 100644 --- a/src/Telegram.Bot/Types/WebAppInfo.cs +++ b/src/Telegram.Bot/Types/WebAppInfo.cs @@ -1,4 +1,4 @@ -namespace Telegram.Bot.Types; +namespace Telegram.Bot.Types; /// /// Contains information about a Web App @@ -11,5 +11,17 @@ public class WebAppInfo /// Initializing Web Apps /// [JsonProperty(Required = Required.Always)] - public string Url { get; set; } = default!; + public string Url { get; } + + /// + /// Initializes a new instance of the class with url + /// + /// + /// An HTTPS URL of a Web App to be opened with additional data as specified in + /// Initializing Web Apps + /// + public WebAppInfo(string url) + { + Url = url; + } } From 744caa2207628ec036576d23ca239fb8a62c5431 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Sat, 6 Jan 2024 02:19:49 +0300 Subject: [PATCH 32/90] Button tests: * Fix WebApp test * Modernize Inline Keyboard tests * Add RequestUsers and RequestChat tests --- .../PrivateChatReplyMarkupTests.cs | 95 ++++++++++++++----- .../ReplyMarkup/ReplyMarkupTests.cs | 93 +++++++----------- .../MenuButtonSerializationTests.cs | 4 +- 3 files changed, 107 insertions(+), 85 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs index e86124703..fe1e83b4d 100644 --- a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs +++ b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs @@ -11,26 +11,20 @@ namespace Telegram.Bot.Tests.Integ.ReplyMarkup; [Collection(Constants.TestCollections.PrivateChatReplyMarkup)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class PrivateChatReplyMarkupTests : IClassFixture +public class PrivateChatReplyMarkupTests(TestsFixture testsFixture, PrivateChatReplyMarkupTests.Fixture fixture) : IClassFixture { ITelegramBotClient BotClient => _fixture.BotClient; - readonly Fixture _classFixture; + readonly Fixture _classFixture = fixture; + readonly TestsFixture _fixture = testsFixture; - readonly TestsFixture _fixture; - - public PrivateChatReplyMarkupTests(TestsFixture testsFixture, Fixture fixture) - { - _fixture = testsFixture; - _classFixture = fixture; - } - - [OrderedFact("Should get contact info from keyboard reply markup")] + [OrderedFact("Should request contact with keyboard reply markup")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] - public async Task Should_Receive_Contact_Info() + public async Task Should_Request_Contact() { - ReplyKeyboardMarkup replyKeyboardMarkup = new ( - keyboardRow: new[] { KeyboardButton.WithRequestContact("Share Contact"), }) + KeyboardButton[] keyboard = [KeyboardButton.WithRequestContact("Share Contact"),]; + + ReplyKeyboardMarkup replyKeyboardMarkup = new (keyboardRow: keyboard) { ResizeKeyboard = true, OneTimeKeyboard = true, @@ -56,14 +50,17 @@ await BotClient.SendTextMessageAsync( ); } - [OrderedFact("Should get location from keyboard reply markup")] + [OrderedFact("Should request location with keyboard reply markup")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] - public async Task Should_Receive_Location() + public async Task Should_Request_Location() { + KeyboardButton[] keyboard = [KeyboardButton.WithRequestLocation("Share Location")]; + ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); + await BotClient.SendTextMessageAsync( chatId: _classFixture.PrivateChat, text: "Share your location using the keyboard reply markup", - replyMarkup: new ReplyKeyboardMarkup(KeyboardButton.WithRequestLocation("Share Location")) + replyMarkup: replyKeyboardMarkup ); Message locationMessage = await GetMessageFromChat(MessageType.Location); @@ -77,6 +74,63 @@ await BotClient.SendTextMessageAsync( ); } + [OrderedFact("Should request users with keyboard reply markup")] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] + public async Task Should_Request_Users() + { + KeyboardButton[] keyboard = + [ + KeyboardButton.WithRequestUsers(text: "Share Users", requestId: 1) + ]; + ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); + + await BotClient.SendTextMessageAsync( + chatId: _classFixture.PrivateChat, + text: "Share users using the keyboard reply markup", + replyMarkup: replyKeyboardMarkup + ); + + Message usersMessage = await GetMessageFromChat(MessageType.UsersShared); + + Assert.NotNull(usersMessage.UsersShared); + + await BotClient.SendTextMessageAsync( + chatId: _classFixture.PrivateChat, + text: "Got it. Removing reply keyboard markup...", + replyMarkup: new ReplyKeyboardRemove() + ); + } + + [OrderedFact("Should request chat with keyboard reply markup")] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] + public async Task Should_Request_Chat() + { + KeyboardButton[] keyboard = + [ + KeyboardButton.WithRequestChat( + text: "Share Chat", + requestId: 1, + chatIsChannel: false) + ]; + ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); + + await BotClient.SendTextMessageAsync( + chatId: _classFixture.PrivateChat, + text: "Share chat using the keyboard reply markup", + replyMarkup: replyKeyboardMarkup + ); + + Message chatMessage = await GetMessageFromChat(MessageType.ChatShared); + + Assert.NotNull(chatMessage.ChatShared); + + await BotClient.SendTextMessageAsync( + chatId: _classFixture.PrivateChat, + text: "Got it. Removing reply keyboard markup...", + replyMarkup: new ReplyKeyboardRemove() + ); + } + async Task GetMessageFromChat(MessageType messageType) => (await _fixture.UpdateReceiver.GetUpdateAsync( predicate: u => u.Message!.Type == messageType && @@ -84,10 +138,7 @@ async Task GetMessageFromChat(MessageType messageType) => updateTypes: UpdateType.Message )).Message; - public class Fixture : PrivateChatFixture + public class Fixture(TestsFixture testsFixture) : PrivateChatFixture(testsFixture, Constants.TestCollections.ReplyMarkup) { - public Fixture(TestsFixture testsFixture) - : base(testsFixture, Constants.TestCollections.ReplyMarkup) - { } } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs index 9a0516738..a9dd301e4 100644 --- a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs +++ b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs @@ -9,16 +9,11 @@ namespace Telegram.Bot.Tests.Integ.ReplyMarkup; [Collection(Constants.TestCollections.ReplyMarkup)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ReplyMarkupTests +public class ReplyMarkupTests(TestsFixture testsFixture) { ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; - - public ReplyMarkupTests(TestsFixture testsFixture) - { - _fixture = testsFixture; - } + readonly TestsFixture _fixture = testsFixture; [OrderedFact("Should send a message with force reply markup")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] @@ -35,10 +30,16 @@ await BotClient.SendTextMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Send_MultiRow_Keyboard() { - ReplyKeyboardMarkup replyMarkup = new[] { - new[] { "Top-Left", "Top" , "Top-Right" }, - new[] { "Left", "Center", "Right" }, - new[] { "Bottom-Left", "Bottom", "Bottom-Right" }, + KeyboardButton[][] keyboard = + [ + ["Top-Left", "Top" , "Top-Right"], + ["Left", "Center", "Right"], + ["Bottom-Left", "Bottom", "Bottom-Right"], + ]; + + ReplyKeyboardMarkup replyMarkup = new(keyboard: keyboard) + { + ResizeKeyboard = true, }; await BotClient.SendTextMessageAsync( @@ -63,59 +64,29 @@ await BotClient.SendTextMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Send_Inline_Keyboard() { + InlineKeyboardButton[][] keyboard = + [ + [ + InlineKeyboardButton.WithUrl( + text: "Link to Repository", + url: "https://github.com/TelegramBots/Telegram.Bot"), + ], + [ + InlineKeyboardButton.WithCallbackData(textAndCallbackData: "callback_data1"), + InlineKeyboardButton.WithCallbackData(text: "callback_data: a2", callbackData: "data"), + ], + [InlineKeyboardButton.WithSwitchInlineQuery(text: "switch_inline_query"),], + [InlineKeyboardButton.WithSwitchInlineQueryCurrentChat(text: "switch_inline_query_current_chat"),], + ]; + + InlineKeyboardMarkup replyMarkup = new(keyboard); + Message sentMessage = await BotClient.SendTextMessageAsync( chatId: _fixture.SupergroupChat, text: "Message with inline keyboard markup", - replyMarkup: new InlineKeyboardMarkup(new[] - { - new [] - { - InlineKeyboardButton.WithUrl( - "Link to Repository", - "https://github.com/TelegramBots/Telegram.Bot" - ), - }, - new [] - { - InlineKeyboardButton.WithCallbackData("callback_data1"), - InlineKeyboardButton.WithCallbackData("callback_data2", "data"), - }, - new [] { InlineKeyboardButton.WithSwitchInlineQuery("switch_inline_query"), }, - new [] { InlineKeyboardButton.WithSwitchInlineQueryCurrentChat("switch_inline_query_current_chat"), }, - }) + replyMarkup: replyMarkup ); - Assert.True( - JToken.DeepEquals( - JToken.FromObject(sentMessage.ReplyMarkup), - JToken.FromObject( - new InlineKeyboardMarkup( - new[] - { - new[] - { - InlineKeyboardButton.WithUrl( - "Link to Repository", - "https://github.com/TelegramBots/Telegram.Bot" - ), - }, - new[] - { - InlineKeyboardButton.WithCallbackData("callback_data1"), - InlineKeyboardButton.WithCallbackData("callback_data2", "data"), - }, - new[] - { - InlineKeyboardButton.WithSwitchInlineQuery("switch_inline_query"), - }, - new[] - { - InlineKeyboardButton.WithSwitchInlineQueryCurrentChat("switch_inline_query_current_chat"), - }, - } - ) - ) - ) - ); + Asserts.JsonEquals(replyMarkup, sentMessage.ReplyMarkup); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs index 3d6e058d1..8100e3d29 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs @@ -1,4 +1,4 @@ -using Newtonsoft.Json; +using Newtonsoft.Json; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -35,7 +35,7 @@ public void Should_Serialize_Menu_Button_Web_App() { MenuButtonWebApp webAppButton = new() { - WebApp = new() { Url = "https://example.com/link/to/web/app" }, + WebApp = new(url: "https://example.com/link/to/web/app"), Text = "Test text" }; From 1e3880d9dfd70133d21955f20b2da8e5c5ce9dce Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Sat, 6 Jan 2024 02:22:42 +0300 Subject: [PATCH 33/90] Fix spelling --- .../TelegramBotClientExtensions.ApiMethods.cs | 10 +++++----- .../Admin Bot/ChatMemberAdministrationTests.cs | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 7db23fb83..739b64ffc 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -984,7 +984,7 @@ await botClient.ThrowIfNull() /// of /// /// - /// Pass if the animatopn needs to be covered with a spoiler animation + /// Pass if the animation needs to be covered with a spoiler animation /// /// /// Sends the message silently. Users will receive a notification with no sound @@ -1753,7 +1753,7 @@ await botClient.ThrowIfNull() /// or . Dice can have values 1-6 for /// , and , values 1-5 for /// and , and values 1-64 for - /// . Defauts to + /// . Defaults to /// /// /// Sends the message silently. Users will receive a notification with no sound @@ -2078,7 +2078,7 @@ await botClient.ThrowIfNull() /// permissions; the permission will imply the /// permission. /// - /// Date when restrictions will be lifted for the user, unix time. If user is restricted for more than 366 days or less than 30 seconds from the current time, they are considered to be restricted forever. + /// Date when restrictions will be lifted for this user; Unix time. If 0, then the user is restricted forever /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// @@ -3751,7 +3751,7 @@ await botClient.ThrowIfNull() /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// - /// dentifier of the message to edit + /// Identifier of the message to edit /// New caption of the message, 0-1024 characters after entities parsing /// /// Mode for parsing entities in the new caption. See @@ -4250,7 +4250,7 @@ await botClient.ThrowIfNull() /// /// /// Short name of sticker set, to be used in t.me/addstickers/ URLs (e.g., animals). Can contain - /// only english letters, digits and underscores. Must begin with a letter, can't contain consecutive + /// only English letters, digits and underscores. Must begin with a letter, can't contain consecutive /// underscores and must end in "_by_<bot username>". <bot_username> is case /// insensitive. 1-64 characters /// diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs index 1c4164b8d..10f174639 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs @@ -130,7 +130,7 @@ public async Task Should_Create_Chat_Invite_Link() { DateTime createdAt = DateTime.UtcNow; - // Milliseconds are ignored during conversion to unix timestamp since it counts only up to + // Milliseconds are ignored during conversion to Unix timestamp since it counts only up to // seconds, so for equality to work later on assertion we need to zero out milliseconds DateTime expireDate = createdAt.With(new () {Millisecond = 0}).AddHours(1); From ebb477a6361e9d3a025d64f9aa86a746707a0599 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Sat, 6 Jan 2024 02:23:05 +0300 Subject: [PATCH 34/90] Modernize Stickers Tests --- .../Stickers/StickersTests.cs | 243 ++++++++---------- 1 file changed, 110 insertions(+), 133 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs index fde87771c..10bee59bd 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -27,16 +28,16 @@ public StickersTests(TestsFixture fixture, StickersTestsFixture classFixture) } #region 1. Upload sticker files - [OrderedFact("Shound upload static sticker file")] + [OrderedFact("Should upload static sticker file")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UploadStickerFile)] - public async Task Shound_Upload_Static_Sticker_File() + public async Task Should_Upload_Static_Sticker_File() { - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.StaticFirst); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.StaticFirst); File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, sticker: new InputFileStream(stream), - StickerFormat.Static + stickerFormat: StickerFormat.Static ); Assert.NotEmpty(file.FileId); @@ -45,16 +46,16 @@ public async Task Shound_Upload_Static_Sticker_File() _stickersTestsFixture.TestUploadedStaticStickerFile = file; } - [OrderedFact("Shound upload animated sticker file")] + [OrderedFact("Should upload animated sticker file")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UploadStickerFile)] - public async Task Shound_Upload_Animated_Sticker_File() + public async Task Should_Upload_Animated_Sticker_File() { - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.AnimatedFirst); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.AnimatedFirst); File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, sticker: new InputFileStream(stream), - StickerFormat.Animated + stickerFormat: StickerFormat.Animated ); Assert.NotEmpty(file.FileId); @@ -63,16 +64,16 @@ public async Task Shound_Upload_Animated_Sticker_File() _stickersTestsFixture.TestUploadedAnimatedStickerFile = file; } - [OrderedFact("Shound upload video sticker file")] + [OrderedFact("Should upload video sticker file")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UploadStickerFile)] - public async Task Shound_Upload_Video_Sticker_File() + public async Task Should_Upload_Video_Sticker_File() { - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.VideoFirst); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.VideoFirst); File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, sticker: new InputFileStream(stream), - StickerFormat.Video + stickerFormat: StickerFormat.Video ); Assert.NotEmpty(file.FileId); @@ -83,30 +84,26 @@ public async Task Shound_Upload_Video_Sticker_File() #endregion #region 2. Create sticker sets - [OrderedFact("Shound create new static sticker set")] + [OrderedFact("Should create new static sticker set")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Create_New_Static_Sticker_Set() { - List inputStickers = new List(2); - - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.StaticSecond ); - inputStickers.Add( + List inputStickers = + [ new InputSticker( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis - ) - ); - - inputStickers.Add( + ), new InputSticker( sticker: new InputFileStream(stream, "Static2.webp"), emojiList: _stickersTestsFixture.SecondEmojis - ) - ); + ), + ]; await BotClient.CreateNewStickerSetAsync( userId: _stickersTestsFixture.OwnerUserId, @@ -125,33 +122,28 @@ await BotClient.CreateNewStickerSetAsync( Assert.False(_stickersTestsFixture.TestStaticRegularStickerSet.IsAnimated); Assert.False(_stickersTestsFixture.TestStaticRegularStickerSet.IsVideo); - Assert.True(_stickersTestsFixture.TestStaticRegularStickerSet.Stickers.Length == 2); + Assert.Equal(2, _stickersTestsFixture.TestStaticRegularStickerSet.Stickers.Length); } - [OrderedFact("Shound create new animated sticker set")] + [OrderedFact("Should create new animated sticker set")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Create_New_Animated_Sticker_Set() { - List inputStickers = new List(2); - - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.AnimatedSecond ); - inputStickers.Add( + List inputStickers = [ new InputSticker( sticker: new InputFileId(_stickersTestsFixture.TestUploadedAnimatedStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis - ) - ); - - inputStickers.Add( + ), new InputSticker( sticker: new InputFileStream(stream, "Animated2.webp"), emojiList: _stickersTestsFixture.SecondEmojis - ) - ); + ), + ]; await BotClient.CreateNewStickerSetAsync( userId: _stickersTestsFixture.OwnerUserId, @@ -170,33 +162,28 @@ await BotClient.CreateNewStickerSetAsync( Assert.True(_stickersTestsFixture.TestAnimatedRegularStickerSet.IsAnimated); Assert.False(_stickersTestsFixture.TestAnimatedRegularStickerSet.IsVideo); - Assert.True(_stickersTestsFixture.TestAnimatedRegularStickerSet.Stickers.Length == 2); + Assert.Equal(2, _stickersTestsFixture.TestAnimatedRegularStickerSet.Stickers.Length); } - [OrderedFact("Shound create new video sticker set")] + [OrderedFact("Should create new video sticker set")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Create_New_Video_Sticker_Set() { - List inputStickers = new List(2); - - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.VideoSecond ); - inputStickers.Add( + List inputStickers = [ new InputSticker( sticker: new InputFileId(_stickersTestsFixture.TestUploadedVideoStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis - ) - ); - - inputStickers.Add( + ), new InputSticker( sticker: new InputFileStream(stream, "Video2.webp"), emojiList: _stickersTestsFixture.SecondEmojis - ) - ); + ), + ]; await BotClient.CreateNewStickerSetAsync( userId: _stickersTestsFixture.OwnerUserId, @@ -215,7 +202,7 @@ await BotClient.CreateNewStickerSetAsync( Assert.False(_stickersTestsFixture.TestVideoRegularStickerSet.IsAnimated); Assert.True(_stickersTestsFixture.TestVideoRegularStickerSet.IsVideo); - Assert.True(_stickersTestsFixture.TestVideoRegularStickerSet.Stickers.Length == 2); + Assert.Equal(2, _stickersTestsFixture.TestVideoRegularStickerSet.Stickers.Length); } #endregion @@ -231,11 +218,11 @@ public async Task Should_Send_Static_Sticker() Assert.False(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 2); + Assert.Equal(2, stickerSet.Stickers.Length); Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -272,11 +259,11 @@ public async Task Should_Send_Animated_Sticker() Assert.True(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 2); + Assert.Equal(2, stickerSet.Stickers.Length); Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -313,11 +300,11 @@ public async Task Should_Send_Video_Sticker() Assert.False(stickerSet.IsAnimated); Assert.True(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 2); + Assert.Equal(2, stickerSet.Stickers.Length); Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); @@ -350,11 +337,11 @@ public async Task Should_Send_Video_Sticker() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Add_Sticker_To_Static_Sticker_Set() { - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.StaticThird ); - InputSticker inputSticker = new InputSticker( + InputSticker inputSticker = new( sticker: new InputFileStream(stream, "Static3.png"), emojiList: _stickersTestsFixture.ThirdEmojis ); @@ -373,11 +360,11 @@ await BotClient.AddStickerToSetAsync( Assert.False(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 3); + Assert.Equal(3, stickerSet.Stickers.Length); Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -389,11 +376,11 @@ await BotClient.AddStickerToSetAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Add_Sticker_To_Animated_Sticker_Set() { - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.AnimatedThird ); - InputSticker inputSticker = new InputSticker( + InputSticker inputSticker = new( sticker: new InputFileStream(stream, "Animated3.tgs"), emojiList: _stickersTestsFixture.ThirdEmojis ); @@ -412,11 +399,11 @@ await BotClient.AddStickerToSetAsync( Assert.True(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 3); + Assert.Equal(3, stickerSet.Stickers.Length); Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.True(thirdSticker.IsAnimated); @@ -428,11 +415,11 @@ await BotClient.AddStickerToSetAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Add_Sticker_To_Video_Sticker_Set() { - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.VideoThird ); - InputSticker inputSticker = new InputSticker( + InputSticker inputSticker = new( sticker: new InputFileStream(stream, "Video3.webm"), emojiList: _stickersTestsFixture.ThirdEmojis ); @@ -451,11 +438,11 @@ await BotClient.AddStickerToSetAsync( Assert.False(stickerSet.IsAnimated); Assert.True(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 3); + Assert.Equal(3, stickerSet.Stickers.Length); Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -530,7 +517,7 @@ public async Task Should_Set_First_Sticker_EmojiList() Sticker firstSticker = stickerSet.Stickers.First(); - string thirdEmojisString = string.Join("", _stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, firstSticker.Emoji); @@ -547,7 +534,7 @@ await BotClient.SetStickerEmojiListAsync( Sticker updatedFirstSticker = updatedStickerSet.Stickers.First(); - string firstEmojisString = string.Join("", _stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); Assert.Equal(firstEmojisString, updatedFirstSticker.Emoji); } @@ -559,7 +546,7 @@ await BotClient.SetStickerEmojiListAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Set_First_Sticker_Keywords() { - string[] keywords = new[] { "test", "supertest" }; + string[] keywords = ["test", "supertest"]; StickerSet stickerSet = await BotClient.GetStickerSetAsync( name: _stickersTestsFixture.TestStaticRegularStickerSetName @@ -610,7 +597,7 @@ await BotClient.SetStickerSetTitleAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Set_Sticker_Set_Thumbnail() { - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.Regular.StaticThumbnail ); @@ -632,20 +619,19 @@ await BotClient.SetStickerSetThumbnailAsync( #endregion #region 11. Some exceptions - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to create sticker set with name not ending in _by_")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to create sticker set with name not ending in _by_")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] public async Task Should_Throw_InvalidStickerSetNameException() { const string expectedExceptionMessage = "Bad Request: invalid sticker set name is specified"; - List inputStickers = new List - { + List inputStickers = + [ new InputSticker( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis ) - }; + ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( @@ -660,22 +646,21 @@ public async Task Should_Throw_InvalidStickerSetNameException() Assert.Equal(expectedExceptionMessage, exception.Message); } - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to create sticker with invalid emoji")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to create sticker with invalid emoji")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] public async Task Should_Throw_InvalidStickerEmojisException() { const string expectedExceptionMessage = "Bad Request: can't parse InputSticker: expected a Unicode emoji"; - string[] invalidEmojis = new[] { "INVALID" }; + string[] invalidEmojis = ["INVALID"]; - List inputStickers = new List - { + List inputStickers = + [ new InputSticker( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: invalidEmojis ) - }; + ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( @@ -690,8 +675,7 @@ public async Task Should_Throw_InvalidStickerEmojisException() Assert.Equal(expectedExceptionMessage, exception.Message); } - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to create sticker with invalid dimensions")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to create sticker with invalid dimensions")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] public async Task Should_Throw_InvalidStickerDimensionsException() { @@ -699,15 +683,15 @@ public async Task Should_Throw_InvalidStickerDimensionsException() const string expectedExceptionMessage = "Bad Request: STICKER_PNG_DIMENSIONS"; - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); - List inputStickers = new List - { + List inputStickers = + [ new InputSticker( sticker: new InputFileStream(stream, "logo.png"), emojiList: _stickersTestsFixture.FirstEmojis ) - }; + ]; //New name, because an exception might be thrown: Bad Request: sticker set name is already occupied string newStickerSetName = $"new_{_stickersTestsFixture.TestStaticRegularStickerSetName}"; @@ -725,22 +709,21 @@ public async Task Should_Throw_InvalidStickerDimensionsException() Assert.Equal(expectedExceptionMessage, exception.Message); } - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to create sticker with invalid file size")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to create sticker with invalid file size")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] public async Task Should_Throw_InvalidFileSizeException() { const string expectedExceptionMessage = "Bad Request: file is too big"; - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Apes); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Apes); - List inputStickers = new List - { + List inputStickers = + [ new InputSticker( sticker: new InputFileStream(stream, "apes.jpg"), emojiList: _stickersTestsFixture.FirstEmojis ) - }; + ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( @@ -755,23 +738,22 @@ public async Task Should_Throw_InvalidFileSizeException() Assert.Equal(expectedExceptionMessage, exception.Message); } - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to create sticker set with the same name with ruby photo", Skip = "Bot API Bug")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to create sticker set with the same name with ruby photo", + Skip = "Bot API Bug")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] public async Task Should_Throw_StickerSetNameExistsException() { - const string expectedExceptionMessage = "Bad Request: sticker set name is already occupied"; - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Ruby); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Ruby); - List inputStickers = new List - { + List inputStickers = + [ new InputSticker( sticker: new InputFileStream(stream, "ruby.png"), emojiList: _stickersTestsFixture.FirstEmojis ) - }; + ]; // Telegram for some reason does not return an error, so the test is skipped ApiRequestException exception = await Assert.ThrowsAsync(() => @@ -787,8 +769,7 @@ public async Task Should_Throw_StickerSetNameExistsException() Assert.Equal(expectedExceptionMessage, exception.Message); } - [OrderedFact("Should throw " + nameof(ApiRequestException) + - " while trying to remove the last sticker in the set twice")] + [OrderedFact($"Should throw {nameof(ApiRequestException)} while trying to remove the last sticker in the set twice")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteStickerFromSet)] public async Task Should_Throw_StickerSetNotModifiedException() @@ -805,8 +786,10 @@ await BotClient.DeleteStickerFromSetAsync( sticker: new InputFileId(lastSticker.FileId) ); - ApiRequestException exception = await Assert.ThrowsAsync(() => - BotClient.DeleteStickerFromSetAsync( + await Task.Delay(TimeSpan.FromSeconds(10)); + + ApiRequestException exception = await Assert.ThrowsAsync(async () => + await BotClient.DeleteStickerFromSetAsync( sticker: new InputFileId(lastSticker.FileId) ) ); @@ -862,23 +845,20 @@ await BotClient.DeleteStickerSetAsync( #endregion #region 13. Mask tests - [OrderedFact("Shound create new mask static sticker set")] + [OrderedFact("Should create new mask static sticker set")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Create_New_Mask_Static_Sticker_Set() { - List inputStickers = new List(1); - - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Photos.Tux ); - inputStickers.Add( + List inputStickers = [ new InputSticker( sticker: new InputFileStream(stream, "tux.png"), - emojiList: _stickersTestsFixture.SecondEmojis - ) - ); + emojiList: _stickersTestsFixture.SecondEmojis) + ]; await BotClient.CreateNewStickerSetAsync( userId: _stickersTestsFixture.OwnerUserId, @@ -898,7 +878,7 @@ await BotClient.CreateNewStickerSetAsync( Assert.Equal(StickerType.Mask, _stickersTestsFixture.TestStaticMaskStickerSet.StickerType); Assert.False(_stickersTestsFixture.TestStaticMaskStickerSet.IsAnimated); Assert.False(_stickersTestsFixture.TestStaticMaskStickerSet.IsVideo); - Assert.True(_stickersTestsFixture.TestStaticMaskStickerSet.Stickers.Length == 1); + Assert.Single(_stickersTestsFixture.TestStaticMaskStickerSet.Stickers); } [OrderedFact("Should add VLC logo sticker with mask position like hat on forehead")] @@ -906,10 +886,9 @@ await BotClient.CreateNewStickerSetAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Add_Sticker_With_Mask_Position_To_Set() { + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Vlc); - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Vlc); - - InputSticker inputSticker = new InputSticker( + InputSticker inputSticker = new( sticker: new InputFileStream(stream, "vlc.png"), emojiList: _stickersTestsFixture.SecondEmojis ) @@ -936,7 +915,7 @@ await BotClient.AddStickerToSetAsync( Assert.Equal(StickerType.Mask, stickerSet.StickerType); Assert.False(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 2); + Assert.Equal(2, stickerSet.Stickers.Length); Sticker sticker = stickerSet.Stickers.Last(); @@ -949,7 +928,7 @@ await BotClient.AddStickerToSetAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AddStickerToSet)] public async Task Should_Set_Mask_Position_From_Last_Sticker() { - MaskPosition newMaskPosition = new MaskPosition + MaskPosition newMaskPosition = new() { Point = MaskPositionPoint.Chin, Scale = .42f @@ -990,7 +969,7 @@ await BotClient.DeleteStickerSetAsync( name: _stickersTestsFixture.TestStaticMaskStickerSetName ); - await Task.Delay(1_000); + await Task.Delay(TimeSpan.FromSeconds(10)); ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.GetStickerSetAsync( @@ -1003,23 +982,21 @@ await BotClient.DeleteStickerSetAsync( #endregion #region 14. Custom emoji tests - [OrderedFact("Shound create new custom emoji static sticker set")] + [OrderedFact("Should create new custom emoji static sticker set")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CreateNewStickerSet)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Create_New_Custom_Emoji_Static_Sticker_Set() { - List inputStickers = new List(1); - - using System.IO.Stream stream = System.IO.File.OpenRead( + await using System.IO.Stream stream = System.IO.File.OpenRead( Constants.PathToFile.Sticker.CustomEmoji.StaticFirst ); - inputStickers.Add( + List inputStickers = + [ new InputSticker( sticker: new InputFileStream(stream, "Static1.png"), - emojiList: _stickersTestsFixture.FirstEmojis - ) - ); + emojiList: _stickersTestsFixture.FirstEmojis) + ]; await BotClient.CreateNewStickerSetAsync( userId: _stickersTestsFixture.OwnerUserId, @@ -1039,7 +1016,7 @@ await BotClient.CreateNewStickerSetAsync( Assert.Equal(StickerType.CustomEmoji, _stickersTestsFixture.TestStaticCustomEmojiStickerSet.StickerType); Assert.False(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.IsAnimated); Assert.False(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.IsVideo); - Assert.True(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.Stickers.Length == 1); + Assert.Single(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.Stickers); } [OrderedFact("Should add sticker to a custom emoji set")] @@ -1047,9 +1024,9 @@ await BotClient.CreateNewStickerSetAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetStickerSet)] public async Task Should_Add_Sticker_To_A_Custom_Emoji_set() { - using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.CustomEmoji.StaticSecond); + await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.CustomEmoji.StaticSecond); - InputSticker inputSticker = new InputSticker( + InputSticker inputSticker = new( sticker: new InputFileStream(stream, "Static2.png"), emojiList: _stickersTestsFixture.SecondEmojis ); @@ -1069,7 +1046,7 @@ await BotClient.AddStickerToSetAsync( Assert.Equal(StickerType.CustomEmoji, stickerSet.StickerType); Assert.False(stickerSet.IsAnimated); Assert.False(stickerSet.IsVideo); - Assert.True(stickerSet.Stickers.Length == 2); + Assert.Equal(2, stickerSet.Stickers.Length); Sticker sticker = stickerSet.Stickers.Last(); @@ -1101,8 +1078,8 @@ await BotClient.SetCustomEmojiStickerSetThumbnailAsync( Assert.NotNull(changedStickerSet.Thumbnail); Assert.NotNull(changedStickerSet.Thumbnail.FileSize); Assert.True(changedStickerSet.Thumbnail.FileSize > 0); - Assert.True(changedStickerSet.Thumbnail.Width == 100); - Assert.True(changedStickerSet.Thumbnail.Height == 100); + Assert.Equal(100, changedStickerSet.Thumbnail.Width); + Assert.Equal(100, changedStickerSet.Thumbnail.Height); } [OrderedFact("Should delete custom emoji sticker set")] From 6b5a82cabff216e62bf4bb37243e5ca9592eebfe Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Sat, 6 Jan 2024 02:27:44 +0300 Subject: [PATCH 35/90] Multiple Message Actions: * Add CopyMessages and DeleteMessages tests --- .../Framework/Constants.cs | 4 + .../Sending Messages/CopyMessageTests.cs | 42 +++++++--- .../Sending Messages/VideoMessageTests.cs | 76 +++++++++++++++++-- .../Update Messages/DeleteMessageTests2.cs | 36 +++++++-- 4 files changed, 135 insertions(+), 23 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Framework/Constants.cs b/test/Telegram.Bot.Tests.Integ/Framework/Constants.cs index 4227fd681..44e0ebb69 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/Constants.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/Constants.cs @@ -328,6 +328,8 @@ public static class TelegramBotApiMethods public const string DeleteMessage = "deleteMessage"; + public const string DeleteMessages = "deleteMessages"; + public const string SendLocation = "sendLocation"; public const string EditMessageLiveLocation = "editMessageLiveLocation"; @@ -402,6 +404,8 @@ public static class TelegramBotApiMethods public const string CopyMessage = "copyMessage"; + public const string CopyMessages = "copyMessages"; + public const string UnpinAllChatMessages = "unpinAllChatMessages"; } } diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs index 1b10a85ed..8b42027bd 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs @@ -7,16 +7,11 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendCopyMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class CopyMessageTests +public class CopyMessageTests(TestsFixture testsFixture) { ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; - - public CopyMessageTests(TestsFixture testsFixture) - { - _fixture = testsFixture; - } + readonly TestsFixture _fixture = testsFixture; [OrderedFact("Should copy text message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CopyMessage)] @@ -28,11 +23,36 @@ public async Task Should_Copy_Text_Message() ); MessageId copyMessageId = await BotClient.CopyMessageAsync( - _fixture.SupergroupChat.Id, - _fixture.SupergroupChat.Id, - message.MessageId + chatId: _fixture.SupergroupChat.Id, + fromChatId: _fixture.SupergroupChat.Id, + messageId: message.MessageId ); Assert.NotEqual(0, copyMessageId.Id); } -} \ No newline at end of file + + [OrderedFact("Should copy text messages")] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CopyMessages)] + public async Task Should_Copy_Text_Messages() + { + Message message1 = await BotClient.SendTextMessageAsync( + chatId: _fixture.SupergroupChat.Id, + text: "message one." + ); + + Message message2 = await BotClient.SendTextMessageAsync( + chatId: _fixture.SupergroupChat.Id, + text: "message two" + ); + + int[] messageIds = [message1.MessageId, message2.MessageId]; + + MessageId[] copyMessageIds = await BotClient.CopyMessagesAsync( + chatId: _fixture.SupergroupChat.Id, + fromChatId: _fixture.SupergroupChat.Id, + messageIds: messageIds + ); + + Assert.Equal(2, copyMessageIds.Length); + } +} diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs index 499e2d733..0483b6af5 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs @@ -1,5 +1,7 @@ using System.IO; +using System.Net.Http; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -65,10 +67,10 @@ public async Task Should_Send_Video_Note() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Videos.GoldenRatio)) { message = await BotClient.SendVideoNoteAsync( - chatId: _fixture.SupergroupChat.Id, + chatId: _fixture.SupergroupChat.Id, videoNote: new InputFileStream(stream), - duration: 28, - length: 240 + duration: 28, + length: 240 ); } @@ -111,7 +113,7 @@ public async Task Should_Send_Video_With_Thumb() Assert.Equal(320, message.Video.Thumbnail.Width); Assert.Equal(240, message.Video.Thumbnail.Height); Assert.NotNull(message.Video.Thumbnail.FileSize); - Assert.InRange((int)message.Video.Thumbnail.FileSize, 600, 900); + Assert.InRange((long)message.Video.Thumbnail.FileSize, 600, 900); } [OrderedFact("Should send a video note with thumbnail")] @@ -125,7 +127,7 @@ public async Task Should_Send_Video_Note_With_Thumb() ) { message = await BotClient.SendVideoNoteAsync( - chatId: _fixture.SupergroupChat.Id, + chatId: _fixture.SupergroupChat.Id, videoNote: new InputFileStream(stream1), thumbnail: new InputFileStream(stream2, "thumbnail.jpg") ); @@ -140,4 +142,68 @@ public async Task Should_Send_Video_Note_With_Thumb() Assert.NotNull(message.VideoNote.Thumbnail.FileSize); Assert.InRange((int)message.VideoNote.Thumbnail.FileSize, 1_000, 1_500); } + + [OrderedFact("Should cache content")] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVideoNote)] + public async Task Should_Cache_Content() + { + await using Stream + stream1 = System.IO.File.OpenRead(Constants.PathToFile.Videos.GoldenRatio), + stream2 = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); + + SendVideoRequest sendVideoRequest1 = new( + chatId: 999999, + video: new InputFileStream(stream1, "file")) + { + Thumbnail = new InputFileStream(stream2, "thumb.jpg"), + }; + + SendVideoRequest sendVideoRequest2 = new( + chatId: 999999, + video: new InputFileStream(stream1, "file")) + { + Thumbnail = new InputFileStream(stream2, "thumb.jpg"), + }; + + /* + StreamContent[] t1 = await Task.WhenAll( + sendVideoRequest1.CachedContent(), + sendVideoRequest2.CachedContent()); + + StreamContent[] t2 = await Task.WhenAll( + sendVideoRequest1.CachedContent(), + sendVideoRequest2.CachedContent()); + + string[] c1 = await Task.WhenAll( + t1[0]!.ReadAsStringAsync(), + t1[1]!.ReadAsStringAsync()); + + string[] c2 = await Task.WhenAll( + t2[0]!.ReadAsStringAsync(), + t2[1]!.ReadAsStringAsync()); + + Assert.Equal(c1[0], c2[0]); + Assert.Equal(c2[1], c2[1]); + //*/ + + /* + string[] c1 = await Task.WhenAll( + sendVideoRequest1.CachedContent()!.ReadAsStringAsync(), + sendVideoRequest2.CachedContent()!.ReadAsStringAsync()); + + string[] c2 = await Task.WhenAll( + sendVideoRequest1.CachedContent()!.ReadAsStringAsync(), + sendVideoRequest2.CachedContent()!.ReadAsStringAsync()); + + Assert.Equal(c1[0], c2[0]); + Assert.Equal(c2[1], c2[1]); + */ + + /* + string hc1 = await sendVideoRequest1.ToHttpContent().ReadAsStringAsync(); + string hc2 = await sendVideoRequest1.ToHttpContent().ReadAsStringAsync(); + + Assert.Equal(hc1, hc2); + */ + } } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs index 74296bcd8..cdbcd3588 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs @@ -7,16 +7,12 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.DeleteMessage2)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class DeleteMessageTests2 +public class DeleteMessageTests2(TestsFixture fixture) { ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; + readonly TestsFixture _fixture = fixture; - public DeleteMessageTests2(TestsFixture fixture) - { - _fixture = fixture; - } [OrderedFact("Should delete message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] @@ -35,4 +31,30 @@ await BotClient.DeleteMessageAsync( messageId: message.MessageId ); } -} \ No newline at end of file + + [OrderedFact("Should delete messages")] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] + [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteMessages)] + public async Task Should_Delete_Messages() + { + Message message1 = await BotClient.SendTextMessageAsync( + chatId: _fixture.SupergroupChat.Id, + text: "Message one.\nThis message will be deleted shortly" + ); + + Message message2 = await BotClient.SendTextMessageAsync( + chatId: _fixture.SupergroupChat.Id, + text: "Message two.\nThis message will be deleted shortly" + ); + + int[] messageIds = [message1.MessageId, message2.MessageId]; + + await Task.Delay(1_000); + + await BotClient.DeleteMessagesAsync( + chatId: _fixture.SupergroupChat.Id, + messageIds: messageIds + ); + } + +} From 575697e78b42fd283b11b3cab38709721633e0b1 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:21:47 +0300 Subject: [PATCH 36/90] Get rid of Polly dependency --- .../Getting Updates/WebhookTests.cs | 18 +++++------------- .../Telegram.Bot.Tests.Integ.csproj | 1 - 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs b/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs index ef1b86a17..f4536dcfd 100644 --- a/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Threading.Tasks; -using Polly; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -10,31 +9,24 @@ namespace Telegram.Bot.Tests.Integ.Getting_Updates; +/// Webhook tests /// /// Webhooks must be immediately disabled because the test framework uses getUpdates method. /// [Collection(Constants.TestCollections.Webhook)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class WebhookTests : IDisposable +public class WebhookTests(TestsFixture fixture) : IDisposable { ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; - - public WebhookTests(TestsFixture fixture) - { - _fixture = fixture; - } + readonly TestsFixture _fixture = fixture; /// /// Ensures that the webhooks are immediately disabled after each test case. /// public void Dispose() { - Policy - .Handle() - .WaitAndRetryAsync(new[] {TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(15)}) - .ExecuteAsync(() => BotClient.DeleteWebhookAsync()) + BotClient.DeleteWebhookAsync() .GetAwaiter() .GetResult(); } @@ -53,7 +45,7 @@ public async Task Should_Set_Webhook_With_Options() await BotClient.SetWebhookAsync( url: "https://www.t.me/", maxConnections: 5, - allowedUpdates: new[] {UpdateType.CallbackQuery, UpdateType.InlineQuery} + allowedUpdates: new[] { UpdateType.CallbackQuery, UpdateType.InlineQuery } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj index 429e970f6..9823a6319 100644 --- a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj +++ b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj @@ -15,7 +15,6 @@ - From c14bcb551f375b8ac048e1061773aa58e156941d Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:22:22 +0300 Subject: [PATCH 37/90] Remove Cached Content test --- .../Sending Messages/VideoMessageTests.cs | 64 ------------------- 1 file changed, 64 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs index 0483b6af5..d6e7708da 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs @@ -142,68 +142,4 @@ public async Task Should_Send_Video_Note_With_Thumb() Assert.NotNull(message.VideoNote.Thumbnail.FileSize); Assert.InRange((int)message.VideoNote.Thumbnail.FileSize, 1_000, 1_500); } - - [OrderedFact("Should cache content")] - [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVideoNote)] - public async Task Should_Cache_Content() - { - await using Stream - stream1 = System.IO.File.OpenRead(Constants.PathToFile.Videos.GoldenRatio), - stream2 = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); - - SendVideoRequest sendVideoRequest1 = new( - chatId: 999999, - video: new InputFileStream(stream1, "file")) - { - Thumbnail = new InputFileStream(stream2, "thumb.jpg"), - }; - - SendVideoRequest sendVideoRequest2 = new( - chatId: 999999, - video: new InputFileStream(stream1, "file")) - { - Thumbnail = new InputFileStream(stream2, "thumb.jpg"), - }; - - /* - StreamContent[] t1 = await Task.WhenAll( - sendVideoRequest1.CachedContent(), - sendVideoRequest2.CachedContent()); - - StreamContent[] t2 = await Task.WhenAll( - sendVideoRequest1.CachedContent(), - sendVideoRequest2.CachedContent()); - - string[] c1 = await Task.WhenAll( - t1[0]!.ReadAsStringAsync(), - t1[1]!.ReadAsStringAsync()); - - string[] c2 = await Task.WhenAll( - t2[0]!.ReadAsStringAsync(), - t2[1]!.ReadAsStringAsync()); - - Assert.Equal(c1[0], c2[0]); - Assert.Equal(c2[1], c2[1]); - //*/ - - /* - string[] c1 = await Task.WhenAll( - sendVideoRequest1.CachedContent()!.ReadAsStringAsync(), - sendVideoRequest2.CachedContent()!.ReadAsStringAsync()); - - string[] c2 = await Task.WhenAll( - sendVideoRequest1.CachedContent()!.ReadAsStringAsync(), - sendVideoRequest2.CachedContent()!.ReadAsStringAsync()); - - Assert.Equal(c1[0], c2[0]); - Assert.Equal(c2[1], c2[1]); - */ - - /* - string hc1 = await sendVideoRequest1.ToHttpContent().ReadAsStringAsync(); - string hc2 = await sendVideoRequest1.ToHttpContent().ReadAsStringAsync(); - - Assert.Equal(hc1, hc2); - */ - } } From fd39dd48eba5aea55a37e1ce5432cd97fb3765ed Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 13:22:42 +0300 Subject: [PATCH 38/90] Fix BotShortDescriptionTests --- .../Other/BotShortDescriptionTests.cs | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs index 98e491be3..6c15d22b3 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs @@ -8,23 +8,18 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.BotShortDescription)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class BotShortDescriptionTests: IAsyncLifetime +public class BotShortDescriptionTests(TestsFixture fixture) : IAsyncLifetime { - readonly TestsFixture _fixture; + readonly TestsFixture _fixture = fixture; string _languageCode; ITelegramBotClient BotClient => _fixture.BotClient; - public BotShortDescriptionTests(TestsFixture fixture) - { - _fixture = fixture; - } - [OrderedFact("Should set a new bot short description")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyShortDescription)] public async Task Should_Set_New_Bot__Short_Description() { - string shortDescription = "Test bot short description"; + const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( shortDescription: shortDescription @@ -35,7 +30,7 @@ await BotClient.SetMyShortDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetMyShortDescription)] public async Task Should_Get_Set_Bot_Short_Description() { - string shortDescription = "Test bot short description"; + const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( shortDescription: shortDescription @@ -53,7 +48,7 @@ await BotClient.SetMyShortDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyShortDescription)] public async Task Should_Delete_Bot_Short_Description() { - string shortDescription = "Test bot short description"; + const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( shortDescription: shortDescription @@ -68,7 +63,8 @@ await BotClient.SetMyShortDescriptionAsync( shortDescription: "" ); - await Task.Delay(TimeSpan.FromSeconds(10)); + // Test fails receiving old description without a delay + await Task.Delay(TimeSpan.FromSeconds(20)); BotShortDescription currentShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); @@ -80,7 +76,7 @@ await BotClient.SetMyShortDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyShortDescription)] public async Task Should_Set_Short_Description_With_Language_Code_Area() { - string shortDescription = "Короткое тестовое описание бота"; + const string shortDescription = "Короткое тестовое описание бота"; _languageCode = "ru"; From 34e71064c470ede5f957544c03236961cde5ffad Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:10:39 +0300 Subject: [PATCH 39/90] Modernize test framework classes --- .../Framework/TestsFixture.cs | 19 +++++++-------- .../Framework/UpdateReceiver.cs | 24 +++++++------------ 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs index 0d8a832b7..aedc8c9ad 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs @@ -138,17 +138,14 @@ bool IsMatch(Update u) => public async Task GetChatFromAdminAsync() { - static bool IsMatch(Update u) => u is - { - Message: - { - Type: MessageType.Contact, - ForwardOrigin: not null, - NewChatMembers.Length: > 0, - } - }; + static bool IsMatch(Update u) => u + is { Message.Type: MessageType.Contact } + or { Message.NewChatMembers.Length: > 0 } + or { Message.ForwardOrigin: not null }; + + await UpdateReceiver.DiscardNewUpdatesAsync(); - var update = await UpdateReceiver.GetUpdateAsync(IsMatch, updateTypes: UpdateType.Message); + var update = await UpdateReceiver.GetUpdateAsync(IsMatch, updateTypes: [UpdateType.Message, UpdateType.ChatMember]); await UpdateReceiver.DiscardNewUpdatesAsync(); @@ -306,7 +303,7 @@ async ValueTask OnMakingApiRequest( } } - multipartContent = stringifiedFormContent.ToArray(); + multipartContent = [.. stringifiedFormContent]; } else { diff --git a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs index f849ad171..b5061fa2e 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs @@ -17,17 +17,11 @@ public enum UpdatePosition Single } -public class UpdateReceiver +public class UpdateReceiver(ITelegramBotClient botClient, IEnumerable? allowedUsernames) { - readonly ITelegramBotClient _botClient; + readonly ITelegramBotClient _botClient = botClient; - public List AllowedUsernames { get; } - - public UpdateReceiver(ITelegramBotClient botClient, IEnumerable? allowedUsernames) - { - _botClient = botClient; - AllowedUsernames = allowedUsernames?.ToList() ?? []; - } + public List AllowedUsernames { get; } = allowedUsernames?.ToList() ?? []; public async Task DiscardNewUpdatesAsync(CancellationToken cancellationToken = default) { @@ -47,7 +41,7 @@ public async Task DiscardNewUpdatesAsync(CancellationToken cancellationToken = d { var updates = await _botClient.GetUpdatesAsync( offset: offset, - allowedUpdates: Array.Empty(), + allowedUpdates: Enum.GetValues().Where(u => u != UpdateType.Unknown), cancellationToken: cancellationToken ); @@ -145,7 +139,7 @@ public async Task GetCallbackQueryUpdateAsync( var updates = await GetUpdatesAsync( predicate: u => (messageId is null || ((Message?)u.CallbackQuery?.Message)?.MessageId == messageId) && (data is null || u.CallbackQuery?.Data == data), - updateTypes: new [] { UpdateType.CallbackQuery }, + updateTypes: [UpdateType.CallbackQuery], cancellationToken: cancellationToken ); @@ -243,10 +237,10 @@ or UpdateType.PollAnswer or UpdateType.ChatMember or UpdateType.MyChatMember or UpdateType.ChatJoinRequest => - AllowedUsernames.Contains( - update.GetUser().Username, - StringComparer.OrdinalIgnoreCase - ), + AllowedUsernames.Contains( + update.GetUser().Username, + StringComparer.OrdinalIgnoreCase + ), UpdateType.Poll => true, UpdateType.EditedMessage or UpdateType.ChannelPost From 4c04bb959943fa1db17c0561c7f98be095d27cd4 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:13:35 +0300 Subject: [PATCH 40/90] Modernize Admin Bot tests --- .../Admin Bot/ChannelAdminBotTests.cs | 13 ++++--------- .../ChatMemberAdministrationTestFixture.cs | 9 ++++----- .../Admin Bot/ChatMemberAdministrationTests.cs | 13 ++++--------- .../Admin Bot/SupergroupAdminBotTests.cs | 14 +++++--------- 4 files changed, 17 insertions(+), 32 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs index c009fe303..ad0f757ab 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs @@ -10,20 +10,15 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; [Collection(Constants.TestCollections.ChannelAdminBots)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ChannelAdminBotTests : IClassFixture +public class ChannelAdminBotTests(TestsFixture testsFixture, ChannelAdminBotTestFixture classFixture) + : IClassFixture { - readonly ChannelAdminBotTestFixture _classFixture; + readonly ChannelAdminBotTestFixture _classFixture = classFixture; - readonly TestsFixture _fixture; + readonly TestsFixture _fixture = testsFixture; ITelegramBotClient BotClient => _fixture.BotClient; - public ChannelAdminBotTests(TestsFixture testsFixture, ChannelAdminBotTestFixture classFixture) - { - _fixture = testsFixture; - _classFixture = classFixture; - } - #region 1. Changing Chat Title [OrderedFact("Should set chat title")] diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs index e36aef78f..59b58dc75 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs @@ -6,11 +6,10 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; -public class ChatMemberAdministrationTestFixture : IAsyncLifetime +public class ChatMemberAdministrationTestFixture(TestsFixture testsFixture) + : IAsyncLifetime { - readonly TestsFixture _testsFixture; - - public ChatMemberAdministrationTestFixture(TestsFixture testsFixture) => _testsFixture = testsFixture; + readonly TestsFixture _testsFixture = testsFixture; public Chat RegularMemberChat { get; private set; } public long RegularMemberUserId { get; private set; } @@ -72,4 +71,4 @@ public Task DisposeAsync() _testsFixture.UpdateReceiver.AllowedUsernames.Remove(RegularMemberUserName); return Task.CompletedTask; } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs index 10f174639..9a679e1de 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs @@ -13,19 +13,14 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; [Collection(Constants.TestCollections.ChatMemberAdministration)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ChatMemberAdministrationTests : IClassFixture +public class ChatMemberAdministrationTests(TestsFixture fixture, ChatMemberAdministrationTestFixture classFixture) + : IClassFixture { ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; + readonly TestsFixture _fixture = fixture; - readonly ChatMemberAdministrationTestFixture _classFixture; - - public ChatMemberAdministrationTests(TestsFixture fixture, ChatMemberAdministrationTestFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + readonly ChatMemberAdministrationTestFixture _classFixture = classFixture; #region Kick, Unban, and Invite chat member back diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs index bca714729..befb39cb7 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs @@ -12,17 +12,13 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; [Collection(Constants.TestCollections.SupergroupAdminBots)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SupergroupAdminBotTests : IClassFixture +public class SupergroupAdminBotTests(SupergroupAdminBotTestsFixture classFixture) + : IClassFixture { - readonly SupergroupAdminBotTestsFixture _classFixture; + readonly SupergroupAdminBotTestsFixture _classFixture = classFixture; ITelegramBotClient BotClient => _classFixture.TestsFixture.BotClient; - public SupergroupAdminBotTests(SupergroupAdminBotTestsFixture classFixture) - { - _classFixture = classFixture; - } - #region 1. Changing Chat Title [OrderedFact("Should set chat title")] @@ -258,7 +254,7 @@ public async Task Should_Create_Chat_Invite_Link() { DateTime createdAt = DateTime.UtcNow; - // Milliseconds are ignored during conversion to unix timestamp since it counts only up to + // Milliseconds are ignored during conversion to Unix timestamp since it counts only up to // seconds, so for equality to work later on assertion we need to zero out milliseconds DateTime expireDate = createdAt.With(new () {Millisecond = 0}).AddHours(1); @@ -294,7 +290,7 @@ public async Task Should_Edit_Chat_Invite_Link() { DateTime editedAt = DateTime.UtcNow; - // Milliseconds are ignored during conversion to unix timestamp since it counts only up to + // Milliseconds are ignored during conversion to Unix timestamp since it counts only up to // seconds, so for equality to work later on assertion we need to zero out milliseconds DateTime expireDate = editedAt.With(new () {Millisecond = 0}).AddHours(1); From c3c493ceabc9980ca4de55dd99263319ba608774 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Tue, 9 Jan 2024 17:13:57 +0300 Subject: [PATCH 41/90] Fix ChatMemberAdministrationTests --- .../ChatMemberAdministrationTests.cs | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs index 9a679e1de..ebfe51b63 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs @@ -91,7 +91,7 @@ await _fixture.SendTestInstructionsAsync( await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); - await BotClient.SendTextMessageAsync( + Message privateMessage = await BotClient.SendTextMessageAsync( chatId: _classFixture.RegularMemberChat, text: _classFixture.GroupInviteLink ); @@ -104,6 +104,10 @@ await BotClient.SendTextMessageAsync( updateTypes: [UpdateType.Message] ); + await BotClient.DeleteMessageAsync( + chatId: _classFixture.RegularMemberChat, + messageId: privateMessage.MessageId); + await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); Message serviceMsg = update.Message; @@ -127,7 +131,7 @@ public async Task Should_Create_Chat_Invite_Link() // Milliseconds are ignored during conversion to Unix timestamp since it counts only up to // seconds, so for equality to work later on assertion we need to zero out milliseconds - DateTime expireDate = createdAt.With(new () {Millisecond = 0}).AddHours(1); + DateTime expireDate = createdAt.With(new () {Millisecond = 0}).AddHours(24); string inviteLinkName = $"Created at {createdAt:yyyy-MM-ddTHH:mm:ss}"; @@ -157,28 +161,24 @@ public async Task Should_Create_Chat_Invite_Link() public async Task Should_Receive_Chat_Join_Request() { await _fixture.SendTestInstructionsAsync( - $"@{_classFixture.RegularMemberUserName.Replace("_", @"\_")} should send a request to join the" + + $"@{_classFixture.RegularMemberUserName.Replace("_", @"\_")} should send a request to join the " + "chat by following the invite link sent to them in private chat two time. The administrator should " + "decline the first attempt and then approve the second one." ); - await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); - await BotClient.BanChatMemberAsync( chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId - ); + userId: _classFixture.RegularMemberUserId); - await Task.Delay(TimeSpan.FromSeconds(3)); + await Task.Delay(TimeSpan.FromSeconds(5)); await BotClient.UnbanChatMemberAsync( chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId - ); + userId: _classFixture.RegularMemberUserId); - await Task.Delay(TimeSpan.FromSeconds(3)); + await Task.Delay(TimeSpan.FromSeconds(5)); - await BotClient.SendTextMessageAsync( + Message privateMessage = await BotClient.SendTextMessageAsync( chatId: _classFixture.RegularMemberChat, text: _classFixture.ChatInviteLink.InviteLink ); @@ -186,9 +186,14 @@ await BotClient.SendTextMessageAsync( await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); Update update = await _fixture.UpdateReceiver.GetUpdateAsync( - predicate: u => u.ChatJoinRequest is not null + predicate: u => u.ChatJoinRequest is not null, + updateTypes: [UpdateType.ChatJoinRequest] ); + await BotClient.DeleteMessageAsync( + chatId: _classFixture.RegularMemberChat, + messageId: privateMessage.MessageId); + ChatJoinRequest chatJoinRequest = update.ChatJoinRequest; Assert.NotNull(chatJoinRequest); @@ -206,7 +211,6 @@ await BotClient.SendTextMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeclineChatJoinRequest)] public async Task Should_Decline_Chat_Join_Request() { - Exception exception = await Record.ExceptionAsync(async () => await BotClient.DeclineChatJoinRequest( chatId: _fixture.SupergroupChat.Id, @@ -220,11 +224,22 @@ await BotClient.DeclineChatJoinRequest( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.ApproveChatJoinRequest)] public async Task Should_Approve_Chat_Join_Request() { + Message privateMessage = await BotClient.SendTextMessageAsync( + chatId: _classFixture.RegularMemberChat, + text: _classFixture.ChatInviteLink.InviteLink + ); + + await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); + Update update = await _fixture.UpdateReceiver.GetUpdateAsync( predicate: u => u.ChatJoinRequest is not null, - updateTypes: UpdateType.ChatJoinRequest + updateTypes: [UpdateType.ChatJoinRequest] ); + await BotClient.DeleteMessageAsync( + chatId: _classFixture.RegularMemberChat, + messageId: privateMessage.MessageId); + ChatJoinRequest chatJoinRequest = update.ChatJoinRequest; Assert.NotNull(chatJoinRequest); From 204cef12cfb408823c749e2ba6e75df10bd42a12 Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:01:07 +0300 Subject: [PATCH 42/90] Revert "Fix bug #1336" This reverts commit b12fce61413947d5f9f9c4e51996900d65f69787. --- src/Telegram.Bot/Extensions/HttpContentExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Telegram.Bot/Extensions/HttpContentExtensions.cs b/src/Telegram.Bot/Extensions/HttpContentExtensions.cs index 6476c8365..7d043cd71 100644 --- a/src/Telegram.Bot/Extensions/HttpContentExtensions.cs +++ b/src/Telegram.Bot/Extensions/HttpContentExtensions.cs @@ -21,7 +21,6 @@ internal static MultipartFormDataContent AddContentIfInputFile( // It will be dispose of after the request is made #pragma warning disable CA2000 - inputFile.Content.Position = 0; var mediaPartContent = new StreamContent(inputFile.Content) { Headers = From a2243122b448539287b0e4edf5cfbbb9d15ac61c Mon Sep 17 00:00:00 2001 From: karb0f0s <17474471+karb0f0s@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:05:01 +0300 Subject: [PATCH 43/90] Misplaced doc tag in SendVoiceAsync --- src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 739b64ffc..2fde02262 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -1053,10 +1053,10 @@ await botClient.ThrowIfNull() /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// - /// /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only /// + /// /// Audio file to send. Pass a as String to send a file that exists /// on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to get a file from /// the Internet, or upload a new one using multipart/form-data From 6191c9337d570ddaa3f803d9ab0d6caa29bf6677 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:52:23 +0400 Subject: [PATCH 44/90] Use enum instead of string for MessageOrigin type --- .../Converters/MessageOriginConverter.cs | 13 ++-- .../Types/Enums/MessageOriginType.cs | 28 ++++++++ src/Telegram.Bot/Types/MessageOrigin.cs | 19 +++--- .../MessageOriginTypeConverterTests.cs | 67 +++++++++++++++++++ 4 files changed, 112 insertions(+), 15 deletions(-) create mode 100644 src/Telegram.Bot/Types/Enums/MessageOriginType.cs create mode 100644 test/Telegram.Bot.Tests.Unit/EnumConverter/MessageOriginTypeConverterTests.cs diff --git a/src/Telegram.Bot/Converters/MessageOriginConverter.cs b/src/Telegram.Bot/Converters/MessageOriginConverter.cs index 1143264a8..1f4c9168e 100644 --- a/src/Telegram.Bot/Converters/MessageOriginConverter.cs +++ b/src/Telegram.Bot/Converters/MessageOriginConverter.cs @@ -1,5 +1,6 @@ using System.Reflection; using Newtonsoft.Json.Linq; +using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Converters; @@ -32,7 +33,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer JsonSerializer serializer) { var jo = JObject.Load(reader); - var type = jo["type"]?.Value(); + var type = jo["type"]?.Value(); if (type is null) { @@ -41,11 +42,11 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer var actualType = type switch { - "user" => typeof(MessageOriginUser), - "hidden_user" => typeof(MessageOriginHiddenUser), - "chat" => typeof(MessageOriginChat), - "channel" => typeof(MessageOriginChannel), - _ => throw new JsonSerializationException($"Unknown message origin type value of '{jo["type"]}'") + MessageOriginType.User => typeof(MessageOriginUser), + MessageOriginType.HiddenUser => typeof(MessageOriginHiddenUser), + MessageOriginType.Chat => typeof(MessageOriginChat), + MessageOriginType.Channel => typeof(MessageOriginChannel), + _ => throw new JsonSerializationException($"Unknown message origin type value of '{jo["type"]}'") }; // Remove status because status property only has getter diff --git a/src/Telegram.Bot/Types/Enums/MessageOriginType.cs b/src/Telegram.Bot/Types/Enums/MessageOriginType.cs new file mode 100644 index 000000000..c57d5f7d8 --- /dev/null +++ b/src/Telegram.Bot/Types/Enums/MessageOriginType.cs @@ -0,0 +1,28 @@ +namespace Telegram.Bot.Types.Enums; + +/// +/// Message origin type +/// +[JsonConverter(typeof(MessageOriginTypeConverter))] +public enum MessageOriginType +{ + /// + /// + /// + User = 1, + + /// + /// + /// + HiddenUser, + + /// + /// + /// + Chat, + + /// + /// + /// + Channel, +} diff --git a/src/Telegram.Bot/Types/MessageOrigin.cs b/src/Telegram.Bot/Types/MessageOrigin.cs index b67322465..dd401c22c 100644 --- a/src/Telegram.Bot/Types/MessageOrigin.cs +++ b/src/Telegram.Bot/Types/MessageOrigin.cs @@ -1,5 +1,6 @@ using Newtonsoft.Json.Converters; using Telegram.Bot.Converters; +using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Types; @@ -20,7 +21,7 @@ public abstract class MessageOrigin /// Type of the message origin /// [JsonProperty] - public abstract string Type { get; } + public abstract MessageOriginType Type { get; } /// /// Date the message was sent originally @@ -37,9 +38,9 @@ public abstract class MessageOrigin public class MessageOriginUser : MessageOrigin { /// - /// Type of the message origin, always "user" + /// Type of the message origin, always /// - public override string Type => "user"; + public override MessageOriginType Type => MessageOriginType.User; /// [JsonProperty(Required = Required.Always)] @@ -60,9 +61,9 @@ public class MessageOriginUser : MessageOrigin public class MessageOriginHiddenUser : MessageOrigin { /// - /// Type of the message origin, always "hidden_user" + /// Type of the message origin, always /// - public override string Type => "hidden_user"; + public override MessageOriginType Type => MessageOriginType.HiddenUser; /// [JsonProperty(Required = Required.Always)] @@ -83,9 +84,9 @@ public class MessageOriginHiddenUser : MessageOrigin public class MessageOriginChat : MessageOrigin { /// - /// Type of the message origin, always "chat" + /// Type of the message origin, always /// - public override string Type => "chat"; + public override MessageOriginType Type => MessageOriginType.Chat; /// [JsonProperty(Required = Required.Always)] @@ -113,9 +114,9 @@ public class MessageOriginChat : MessageOrigin public class MessageOriginChannel : MessageOrigin { /// - /// Type of the message origin, always "channel" + /// Type of the message origin, always /// - public override string Type => "channel"; + public override MessageOriginType Type => MessageOriginType.Channel; /// [JsonProperty(Required = Required.Always)] diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageOriginTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageOriginTypeConverterTests.cs new file mode 100644 index 000000000..6362f9044 --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageOriginTypeConverterTests.cs @@ -0,0 +1,67 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.EnumConverter; + +public class MessageOriginTypeConverterTests +{ + [Theory] + [InlineData(MessageOriginType.User, "user")] + [InlineData(MessageOriginType.HiddenUser, "hidden_user")] + [InlineData(MessageOriginType.Chat, "chat")] + [InlineData(MessageOriginType.Channel, "channel")] + public void Should_Convert_MessageOriginType_To_String(MessageOriginType messageOriginType, string value) + { + MessageOrigin messageOrigin = new() { Type = messageOriginType }; + string expectedResult = @$"{{""type"":""{value}""}}"; + + string result = JsonConvert.SerializeObject(messageOrigin); + + Assert.Equal(expectedResult, result); + } + + [Theory] + [InlineData(MessageOriginType.User, "user")] + [InlineData(MessageOriginType.HiddenUser, "hidden_user")] + [InlineData(MessageOriginType.Chat, "chat")] + [InlineData(MessageOriginType.Channel, "channel")] + public void Should_Convert_String_To_MessageOriginType(MessageOriginType messageOriginType, string value) + { + MessageOrigin expectedResult = new() { Type = messageOriginType }; + string jsonData = @$"{{""type"":""{value}""}}"; + + MessageOrigin? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal(expectedResult.Type, result.Type); + } + + [Fact] + public void Should_Return_Zero_For_Incorrect_ChatMemberStatus() + { + string jsonData = @$"{{""type"":""{int.MaxValue}""}}"; + + MessageOrigin? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal((MessageOriginType)0, result.Type); + } + + [Fact] + public void Should_Throw_NotSupportedException_For_Incorrect_ChatMemberStatus() + { + MessageOrigin messageOrigin = new() { Type = (MessageOriginType)int.MaxValue }; + + Assert.Throws(() => JsonConvert.SerializeObject(messageOrigin)); + } + + [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] + class MessageOrigin + { + [JsonProperty(Required = Required.Always)] + public MessageOriginType Type { get; init; } + } +} From 971c9a79660275863639c7d3882d56679640a385 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:52:47 +0400 Subject: [PATCH 45/90] Pass cancellation token to CopyToAsync on net6.0+ targets --- src/Telegram.Bot/TelegramBotClient.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Telegram.Bot/TelegramBotClient.cs b/src/Telegram.Bot/TelegramBotClient.cs index d3b0adfd7..39065db50 100644 --- a/src/Telegram.Bot/TelegramBotClient.cs +++ b/src/Telegram.Bot/TelegramBotClient.cs @@ -253,8 +253,13 @@ response.Description is null try { +#if NET6_0_OR_GREATER + await httpResponse.Content.CopyToAsync(destination, cancellationToken) + .ConfigureAwait(false); +#else await httpResponse.Content.CopyToAsync(destination) .ConfigureAwait(false); +#endif } catch (Exception exception) { From cc29dfe8449d9bb47e78b68dbe11017bf91e98d0 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:53:19 +0400 Subject: [PATCH 46/90] Make sure that CLI language is always in English --- Directory.Build.props | 5 +++++ Telegram.Bot.sln | 1 + 2 files changed, 6 insertions(+) create mode 100644 Directory.Build.props diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 000000000..9f6a21db5 --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,5 @@ + + + en + + diff --git a/Telegram.Bot.sln b/Telegram.Bot.sln index db2d533c5..8c5817cac 100644 --- a/Telegram.Bot.sln +++ b/Telegram.Bot.sln @@ -25,6 +25,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore .gitpod.yml = .gitpod.yml LICENSE = LICENSE + Directory.Build.props = Directory.Build.props EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".azure-pipelines", ".azure-pipelines", "{71662597-40F2-4192-AC4D-5FB9A1F12642}" From 43212fc7747ea1b2df5edfd4a4697a7a49d5bc9a Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:53:34 +0400 Subject: [PATCH 47/90] Use C# 12 --- src/Telegram.Bot/Telegram.Bot.csproj | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Telegram.Bot/Telegram.Bot.csproj b/src/Telegram.Bot/Telegram.Bot.csproj index 918a34ffd..5f0458a0c 100644 --- a/src/Telegram.Bot/Telegram.Bot.csproj +++ b/src/Telegram.Bot/Telegram.Bot.csproj @@ -2,7 +2,7 @@ netstandard2.0;net6.0 - 11 + 12 enable True AllEnabledByDefault @@ -51,6 +51,11 @@ 'HttpClient.GetAsync(Uri, HttpCompletionOption, CancellationToken)' instead of 'HttpClient.GetAsync(string, HttpCompletionOption, CancellationToken)' --> $(NoWarn);CA1031 + $(NoWarn);CA1716 + $(NoWarn);CA1510 + $(NoWarn);MA0046 $(NoWarn);MA0048;MA0051 From b3b9aa30bad724008d2179a23d36a4d5f9272141 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:56:14 +0400 Subject: [PATCH 48/90] Update base container to use .NET 8.0 --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 94397f0ca..218ce4781 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -ARG DOTNET_VERSION=6.0 +ARG DOTNET_VERSION=8.0 FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bullseye-slim ARG USERNAME=vscode ARG USER_UID=1000 From 5b2a0c3b1c767d459743aced1680517cc0c72915 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Fri, 16 Feb 2024 21:56:36 +0400 Subject: [PATCH 49/90] Implement Bot API 7.1 --- src/Telegram.Bot/Types/Chat.cs | 15 ++++++++++++ src/Telegram.Bot/Types/ChatBoostAdded.cs | 14 +++++++++++ src/Telegram.Bot/Types/Enums/MessageType.cs | 5 ++++ src/Telegram.Bot/Types/Message.cs | 19 +++++++++++++++ src/Telegram.Bot/Types/Story.cs | 12 ++++++++++ src/Telegram.Bot/Types/TextQuote.cs | 5 ++-- .../Serialization/ChatSerializationTests.cs | 23 +++++++++++++++++++ 7 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/Telegram.Bot/Types/ChatBoostAdded.cs create mode 100644 test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs diff --git a/src/Telegram.Bot/Types/Chat.cs b/src/Telegram.Bot/Types/Chat.cs index 19e02cad1..f1b09a25c 100644 --- a/src/Telegram.Bot/Types/Chat.cs +++ b/src/Telegram.Bot/Types/Chat.cs @@ -192,6 +192,13 @@ public class Chat [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public int? SlowModeDelay { get; set; } + /// + /// Optional. For supergroups, the minimum number of boosts that a non-administrator user needs to add in order + /// to ignore slow mode and chat permissions. Returned only in getChat. + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? UnrestrictBoostCount { get; set; } + /// /// Optional. The time after which all messages sent to the chat will be automatically deleted; in seconds. /// Returned only in . @@ -241,6 +248,14 @@ public class Chat [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? CanSetStickerSet { get; set; } + /// + /// Optional. For supergroups, the name of the group's custom emoji sticker set. Custom emoji from this set can be + /// used by all users and bots in the group. + /// Returned only in . + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public string? CustomEmojiStickerSetName { get; set; } + /// /// Optional. Unique identifier for the linked chat, i.e. the discussion group identifier for a channel /// and vice versa; for supergroups and channel chats. This identifier may be greater than 32 bits and some diff --git a/src/Telegram.Bot/Types/ChatBoostAdded.cs b/src/Telegram.Bot/Types/ChatBoostAdded.cs new file mode 100644 index 000000000..9a0b7f9b3 --- /dev/null +++ b/src/Telegram.Bot/Types/ChatBoostAdded.cs @@ -0,0 +1,14 @@ +namespace Telegram.Bot.Types; + +/// +/// This object represents a service message about a user boosting a chat. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +public class ChatBoostAdded +{ + /// + /// Number of boosts added by the user + /// + [JsonProperty(Required = Required.Always)] + public int BoostCount { get; set; } +} diff --git a/src/Telegram.Bot/Types/Enums/MessageType.cs b/src/Telegram.Bot/Types/Enums/MessageType.cs index 2434c1b42..252cb1b39 100644 --- a/src/Telegram.Bot/Types/Enums/MessageType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageType.cs @@ -265,4 +265,9 @@ public enum MessageType /// The contains a /// GiveawayCompleted, + + /// + /// The contains a + /// + BoostAdded, } diff --git a/src/Telegram.Bot/Types/Message.cs b/src/Telegram.Bot/Types/Message.cs index b3e1e28e3..17b5659db 100644 --- a/src/Telegram.Bot/Types/Message.cs +++ b/src/Telegram.Bot/Types/Message.cs @@ -40,6 +40,12 @@ public class Message : MaybeInaccessibleMessage [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public Chat? SenderChat { get; set; } + /// + /// Optional. If the sender of the message boosted the chat, the number of boosts added by the user + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? SenderBoostCount { get; set; } + /// /// Date the message was sent /// @@ -92,6 +98,12 @@ public class Message : MaybeInaccessibleMessage [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public TextQuote? Quote { get; set; } + /// + /// Optional. For replies to a story, the original story + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public Story? ReplyToStory { get; set; } + /// /// Optional. Bot through which the message was sent /// @@ -407,6 +419,12 @@ Caption is null [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public ProximityAlertTriggered? ProximityAlertTriggered { get; set; } + /// + /// Optional. Service message: user boosted the chat + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public ChatBoostAdded? BoostAdded { get; set; } + /// /// Optional. Service message: forum topic created /// @@ -549,6 +567,7 @@ Caption is null { WriteAccessAllowed: not null } => MessageType.WriteAccessAllowed, { PassportData: not null } => MessageType.PassportData, { ProximityAlertTriggered: not null } => MessageType.ProximityAlertTriggered, + { BoostAdded: not null } => MessageType.BoostAdded, { ForumTopicCreated: not null } => MessageType.ForumTopicCreated, { ForumTopicEdited: not null } => MessageType.ForumTopicEdited, { ForumTopicClosed: not null } => MessageType.ForumTopicClosed, diff --git a/src/Telegram.Bot/Types/Story.cs b/src/Telegram.Bot/Types/Story.cs index 4b70bece2..a160e6a39 100644 --- a/src/Telegram.Bot/Types/Story.cs +++ b/src/Telegram.Bot/Types/Story.cs @@ -6,4 +6,16 @@ namespace Telegram.Bot.Types; [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class Story { + + /// + /// Chat that posted the story + /// + [JsonProperty(Required = Required.Always)] + public Chat Chat { get; set; } = default!; + + /// + /// Unique identifier for the story in the chat + /// + [JsonProperty(Required = Required.Always)] + public int Id { get; set; } } diff --git a/src/Telegram.Bot/Types/TextQuote.cs b/src/Telegram.Bot/Types/TextQuote.cs index 7f93050bd..478e1d6ee 100644 --- a/src/Telegram.Bot/Types/TextQuote.cs +++ b/src/Telegram.Bot/Types/TextQuote.cs @@ -23,10 +23,11 @@ public class TextQuote /// Approximate quote position in the original message in UTF-16 code units as specified by the sender /// [JsonProperty(Required = Required.Always)] - public int Position { get; set; } = default!; + public int Position { get; set; } /// - /// Optional.True, if the quote was chosen manually by the message sender.Otherwise, the quote was added automatically by the server. + /// Optional.True, if the quote was chosen manually by the message sender. + /// Otherwise, the quote was added automatically by the server. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool IsManual { get; set; } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs new file mode 100644 index 000000000..5002f480c --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json; +using Telegram.Bot.Types; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.Serialization; + +public class ChatSerializationTests +{ + [Fact] + public void Should_Deserialize_Chat() + { + Chat chat = new() + { + UnrestrictBoostCount = 10, + CustomEmojiStickerSetName = "test_sticker_set" + }; + + string serializeChat = JsonConvert.SerializeObject(chat); + + Assert.Contains(@"""unrestricted_boost_count"":10", serializeChat); + Assert.Contains(@"""custom_emoji_sticker_set_name"":""test_sticker_set""", serializeChat); + } +} From 0dfbaae1ef98b279cf22547daa19630b56c5ca72 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:21:50 +0400 Subject: [PATCH 50/90] Fix MessageOriginConverter --- src/Telegram.Bot/Converters/MessageOriginConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Telegram.Bot/Converters/MessageOriginConverter.cs b/src/Telegram.Bot/Converters/MessageOriginConverter.cs index 1f4c9168e..11b7e8439 100644 --- a/src/Telegram.Bot/Converters/MessageOriginConverter.cs +++ b/src/Telegram.Bot/Converters/MessageOriginConverter.cs @@ -33,7 +33,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer JsonSerializer serializer) { var jo = JObject.Load(reader); - var type = jo["type"]?.Value(); + var type = jo["type"]?.ToObject(); if (type is null) { From 52b3d4182c81ac1fb8e22451e433175c9268dfb7 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:22:06 +0400 Subject: [PATCH 51/90] Add MessageOrigin serialization tests --- .../MessageOriginSerializationTests.cs | 238 ++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs new file mode 100644 index 000000000..e3fa62dc0 --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs @@ -0,0 +1,238 @@ +using System; +using Newtonsoft.Json; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.Serialization; + +public class MessageOriginSerializationTests +{ + [Fact] + public void Should_Serialize_MessageOriginUser() + { + MessageOriginUser origin = new() + { + SenderUser = new() + { + Id = 12345, + IsBot = true, + FirstName = "First Name", + LastName = "Last Name", + Username = "test_bot", + LanguageCode = "en_US", + }, + Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) + }; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( + JsonConvert.SerializeObject(origin) + ); + Assert.NotNull(messageOrigin); + + MessageOriginUser messageOriginUser = Assert.IsType(messageOrigin); + + Assert.Equal(origin.Date, messageOriginUser.Date); + Assert.Equal(origin.SenderUser.Id, messageOriginUser.SenderUser.Id); + } + + [Fact] + public void Should_Serialize_MessageOriginHidden() + { + MessageOriginHiddenUser origin = new() + { + SenderUserName = "test_bot", + Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) + }; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( + JsonConvert.SerializeObject(origin) + ); + Assert.NotNull(messageOrigin); + + MessageOriginHiddenUser messageOriginHiddenUser = Assert.IsType(messageOrigin); + + Assert.Equal(origin.Date, messageOriginHiddenUser.Date); + Assert.Equal(origin.SenderUserName, origin.SenderUserName); + } + + [Fact] + public void Should_Serialize_MessageOriginChat() + { + MessageOriginChat origin = new() + { + SenderChat = new() + { + Id = 12345, + Type = ChatType.Supergroup, + Username = "test_bot", + IsForum = true, + }, + Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) + }; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( + JsonConvert.SerializeObject(origin) + ); + Assert.NotNull(messageOrigin); + + MessageOriginChat messageOriginChat = Assert.IsType(messageOrigin); + + Assert.Equal(origin.Date, messageOriginChat.Date); + Assert.Equal(origin.SenderChat.Id, messageOriginChat.SenderChat.Id); + Assert.Equal(origin.SenderChat.Type, messageOriginChat.SenderChat.Type); + } + + [Fact] + public void Should_Serialize_MessageOriginChannel() + { + MessageOriginChannel origin = new() + { + Chat = new() + { + Id = 12345, + Type = ChatType.Channel, + Username = "test_channel", + }, + MessageId = 1236886, + AuthorSignature = "author_name", + Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) + }; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( + JsonConvert.SerializeObject(origin) + ); + Assert.NotNull(messageOrigin); + + MessageOriginChannel messageOriginChat = Assert.IsType(messageOrigin); + + Assert.Equal(origin.Date, messageOriginChat.Date); + Assert.Equal(origin.Chat.Id, messageOriginChat.Chat.Id); + Assert.Equal(origin.Chat.Type, messageOriginChat.Chat.Type); + Assert.Equal(origin.AuthorSignature, messageOriginChat.AuthorSignature); + Assert.Equal(origin.MessageId, messageOriginChat.MessageId); + + } + + [Fact] + public void Should_Deserialize_MessageOriginUser() + { + const string origin = + """ + { + "type": "user", + "sender_user": { + "id": 12345, + "is_bot": true, + "first_name": "First Name", + "last_name": "Last Name", + "username": "test_bot", + "language_code": "en_US" + }, + "date": 1708106405 + } + """; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject(origin); + Assert.NotNull(messageOrigin); + + MessageOriginUser originUser = Assert.IsType(messageOrigin); + + Assert.Equal(MessageOriginType.User, messageOrigin.Type); + Assert.Equal(new(2024, 2, 16, 18, 0, 5, 0, DateTimeKind.Utc), originUser.Date); + Assert.NotNull(originUser.SenderUser); + Assert.Equal(12345, originUser.SenderUser.Id); + Assert.True(originUser.SenderUser.IsBot); + Assert.Equal("First Name", originUser.SenderUser.FirstName); + Assert.Equal("Last Name", originUser.SenderUser.LastName); + Assert.Equal("test_bot", originUser.SenderUser.Username); + Assert.Equal("en_US", originUser.SenderUser.LanguageCode); + } + + [Fact] + public void Should_Deserialize_MessageOriginHidden() + { + const string origin = + """ + { + "type": "hidden_user", + "sender_user_name": "test_bot", + "date": 1708106405 + } + """; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject(origin); + Assert.NotNull(messageOrigin); + + MessageOriginHiddenUser originHiddenUser = Assert.IsType(messageOrigin); + + Assert.Equal(MessageOriginType.HiddenUser, messageOrigin.Type); + Assert.Equal(new(2024, 2, 16, 18, 0, 5, 0, DateTimeKind.Utc), originHiddenUser.Date); + Assert.Equal("test_bot", originHiddenUser.SenderUserName); + } + + [Fact] + public void Should_DeSerialize_MessageOriginChat() + { + const string origin = + """ + { + "type": "chat", + "sender_chat": { + "id": 12345, + "type": "supergroup", + "username": "test_bot", + "is_forum": true + }, + "date": 1708106405 + } + """; + + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject(origin); + Assert.NotNull(messageOrigin); + + MessageOriginChat originChat = Assert.IsType(messageOrigin); + + Assert.Equal(MessageOriginType.Chat, messageOrigin.Type); + Assert.Equal(new(2024, 2, 16, 18, 0, 5, 0, DateTimeKind.Utc), originChat.Date); + Assert.NotNull(originChat.SenderChat); + Assert.Equal(12345, originChat.SenderChat.Id); + Assert.True(originChat.SenderChat.IsForum); + Assert.Equal("test_bot", originChat.SenderChat.Username); + } + + [Fact] + public void Should_Deserialize_MessageOriginChannel() + { + const string origin = + """ + { + "type": "channel", + "chat": { + "id": 12345, + "type": "channel", + "username": "test_channel", + "is_forum": true + }, + "message_id": 1236886, + "author_signature": "author_name", + "date": 1708106405 + } + """; + + MessageOrigin? messageOrigin = JsonConvert.DeserializeObject(origin); + Assert.NotNull(messageOrigin); + + MessageOriginChannel originChannel = Assert.IsType(messageOrigin); + + Assert.Equal(MessageOriginType.Channel, messageOrigin.Type); + Assert.Equal(new(2024, 2, 16, 18, 0, 5, 0, DateTimeKind.Utc), originChannel.Date); + Assert.NotNull(originChannel.Chat); + Assert.Equal(12345, originChannel.Chat.Id); + Assert.True(originChannel.Chat.IsForum); + Assert.Equal("test_channel", originChannel.Chat.Username); + Assert.NotNull(originChannel.AuthorSignature); + Assert.Equal("author_name", originChannel.AuthorSignature); + } +} From f13e44caede2b53daff4efc6b3f666b21bbdf8fe Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:30:52 +0400 Subject: [PATCH 52/90] Update CHANGELOG.md --- CHANGELOG.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0763765c1..f0096f32f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,11 +24,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] > [Bot API 7.0](https://core.telegram.org/bots/api#december-29-2023) (December 29, 2023) +> [Bot API 7.1](https://core.telegram.org/bots/api#february-16-2024) (February 16, 2024) ### Added - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. -- The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. +- The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. - Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. - Updates about reaction changes on a message with anonymous reactions, represented by the class `MessageReactionCountUpdated` @@ -61,6 +62,13 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - The properties `AccentColorId`, `BackgroundCustomEmojiId`, `ProfileAccentColorId`, and `ProfileBackgroundCustomEmojiId` to the class `Chat`. - The property `HasVisibleHistory` to the class `Chat`. - Classes `MaybeInaccessibleMessage` and `InaccessibleMessage`. +- The class `ChatBoostAdded` +- Classes `MessageOrigin`, `MessageOriginUser`, `MessageOriginHiddenUser` and `MessageOriginChannel` +- Enum `MessageOriginType` +- Fields `UnrestrictBoostCount` and `CustomEmojiStickerSetName` to type `Chat` +- Enum member `MessageType.BoostAdded` +- Fields `SenderBoostCount`, `ReplyToStory` and `BoostAdded` to type `Message` +- Fields `Chat` and `Id` to type `Story` ### Changed @@ -111,11 +119,15 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Renamed the class `UserShared` to `UsersShared` and changed the property `UserId` to `UserIds`. - Replaced the property `UserShared` in the class Message with the property `UsersShared`. - Replaced enum member `MessageType.UserShared` with `MessageType.UsersShared` -- The class `MessageOrigin` and replaced the fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName` -and `ForwardDate` with the field `ForwardOrigin` of type `MessageOrigin in the class `Message`. +- Fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName` +and `ForwardDate` with the field `ForwardOrigin` of type `MessageOrigin` in the class `Message`. - Type of the property `Message` of the class `CallbackQuery` to `MaybeInaccessibleMessage` - Type of the property `PinnedMessage` of the class `Message` to `MaybeInaccessibleMessage`. +### Removed +- Fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName` + and `ForwardDate` from type `Message` + ## [v20.0.0] - Unreleased > [Bot API 6.9](https://core.telegram.org/bots/api#september-22-2023) (September 22, 2023) From f7d9f56962b9d1ec7b5d223f6f139efb9ecf0260 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:42:33 +0400 Subject: [PATCH 53/90] Add Story serialization tests --- .../Serialization/StorySerializationTests.cs | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs new file mode 100644 index 000000000..890f6bcbf --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs @@ -0,0 +1,56 @@ +using Newtonsoft.Json; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.Serialization; + +public class StorySerializationTests +{ + [Fact] + public void Should_Serialize_Story() + { + Story story = new() + { + Id = 1234, + Chat = new() + { + Id = 876543, + Type = ChatType.Private, + Username = "test_user", + }, + }; + + Story? deserializedStory = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(story)); + + Assert.NotNull(deserializedStory); + Assert.Equal(story.Id, deserializedStory.Id); + Assert.Equal(story.Chat.Id, deserializedStory.Chat.Id); + Assert.Equal(story.Chat.Type, deserializedStory.Chat.Type); + Assert.Equal(story.Chat.Username, deserializedStory.Chat.Username); + } + + [Fact] + public void Should_Deserialize_Story() + { + const string story = + """ + { + "id": 1234, + "chat": { + "id": 876543, + "type": "private", + "username": "test_user", + } + } + """; + + Story? deserializedStory = JsonConvert.DeserializeObject(story); + + Assert.NotNull(deserializedStory); + Assert.Equal(1234, deserializedStory.Id); + Assert.Equal(876543, deserializedStory.Chat.Id); + Assert.Equal(ChatType.Private, deserializedStory.Chat.Type); + Assert.Equal("test_user", deserializedStory.Chat.Username); + } +} From cc19593e3bd9c5749214d7d416fd5fee8a0583f7 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:43:55 +0400 Subject: [PATCH 54/90] Remove unnecessary commas from JSON --- .../Serialization/StorySerializationTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs index 890f6bcbf..4c8bef8e1 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs @@ -17,7 +17,7 @@ public void Should_Serialize_Story() { Id = 876543, Type = ChatType.Private, - Username = "test_user", + Username = "test_user" }, }; @@ -40,7 +40,7 @@ public void Should_Deserialize_Story() "chat": { "id": 876543, "type": "private", - "username": "test_user", + "username": "test_user" } } """; From 9ccba194331c40b9afc1c26fbaea181b80b65a7b Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:47:00 +0400 Subject: [PATCH 55/90] Fix tests --- .../MessageTypeConverterTests.cs | 105 +++++++++--------- .../Serialization/ChatSerializationTests.cs | 2 +- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs index dd4019c34..bd842557b 100644 --- a/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/MessageTypeConverterTests.cs @@ -87,58 +87,59 @@ private class MessageTypeData : IEnumerable { public IEnumerator GetEnumerator() { - yield return new object[] { MessageType.Unknown, "unknown" }; - yield return new object[] { MessageType.Text, "text" }; - yield return new object[] { MessageType.Animation, "animation" }; - yield return new object[] { MessageType.Audio, "audio" }; - yield return new object[] { MessageType.Document, "document" }; - yield return new object[] { MessageType.Photo, "photo" }; - yield return new object[] { MessageType.Sticker, "sticker" }; - yield return new object[] { MessageType.Story, "story" }; - yield return new object[] { MessageType.Video, "video" }; - yield return new object[] { MessageType.VideoNote, "video_note" }; - yield return new object[] { MessageType.Voice, "voice" }; - yield return new object[] { MessageType.Contact, "contact" }; - yield return new object[] { MessageType.Dice, "dice" }; - yield return new object[] { MessageType.Game, "game" }; - yield return new object[] { MessageType.Poll, "poll" }; - yield return new object[] { MessageType.Venue, "venue" }; - yield return new object[] { MessageType.Location, "location" }; - yield return new object[] { MessageType.NewChatMembers, "new_chat_members" }; - yield return new object[] { MessageType.LeftChatMember, "left_chat_member" }; - yield return new object[] { MessageType.NewChatTitle, "new_chat_title" }; - yield return new object[] { MessageType.NewChatPhoto, "new_chat_photo" }; - yield return new object[] { MessageType.DeleteChatPhoto, "delete_chat_photo" }; - yield return new object[] { MessageType.GroupChatCreated, "group_chat_created" }; - yield return new object[] { MessageType.SupergroupChatCreated, "supergroup_chat_created" }; - yield return new object[] { MessageType.ChannelChatCreated, "channel_chat_created" }; - yield return new object[] { MessageType.MessageAutoDeleteTimerChanged, "message_auto_delete_timer_changed" }; - yield return new object[] { MessageType.MigrateToChatId, "migrate_to_chat_id" }; - yield return new object[] { MessageType.MigrateFromChatId, "migrate_from_chat_id" }; - yield return new object[] { MessageType.PinnedMessage, "pinned_message" }; - yield return new object[] { MessageType.Invoice, "invoice" }; - yield return new object[] { MessageType.SuccessfulPayment, "successful_payment" }; - yield return new object[] { MessageType.UsersShared, "users_shared" }; - yield return new object[] { MessageType.ChatShared, "chat_shared" }; - yield return new object[] { MessageType.ConnectedWebsite, "connected_website" }; - yield return new object[] { MessageType.WriteAccessAllowed, "write_access_allowed" }; - yield return new object[] { MessageType.PassportData, "passport_data" }; - yield return new object[] { MessageType.ProximityAlertTriggered, "proximity_alert_triggered" }; - yield return new object[] { MessageType.ForumTopicCreated, "forum_topic_created" }; - yield return new object[] { MessageType.ForumTopicEdited, "forum_topic_edited" }; - yield return new object[] { MessageType.ForumTopicClosed, "forum_topic_closed" }; - yield return new object[] { MessageType.ForumTopicReopened, "forum_topic_reopened" }; - yield return new object[] { MessageType.GeneralForumTopicHidden, "general_forum_topic_hidden" }; - yield return new object[] { MessageType.GeneralForumTopicUnhidden, "general_forum_topic_unhidden" }; - yield return new object[] { MessageType.GiveawayCreated, "giveaway_created" }; - yield return new object[] { MessageType.Giveaway, "giveaway" }; - yield return new object[] { MessageType.GiveawayWinners, "giveaway_winners" }; - yield return new object[] { MessageType.GiveawayCompleted, "giveaway_completed" }; - yield return new object[] { MessageType.VideoChatScheduled, "video_chat_scheduled" }; - yield return new object[] { MessageType.VideoChatStarted, "video_chat_started" }; - yield return new object[] { MessageType.VideoChatEnded, "video_chat_ended" }; - yield return new object[] { MessageType.VideoChatParticipantsInvited, "video_chat_participants_invited" }; - yield return new object[] { MessageType.WebAppData, "web_app_data" }; + yield return [MessageType.Unknown, "unknown"]; + yield return [MessageType.Text, "text"]; + yield return [MessageType.Animation, "animation"]; + yield return [MessageType.Audio, "audio"]; + yield return [MessageType.BoostAdded, "boost_added"]; + yield return [MessageType.Document, "document"]; + yield return [MessageType.Photo, "photo"]; + yield return [MessageType.Sticker, "sticker"]; + yield return [MessageType.Story, "story"]; + yield return [MessageType.Video, "video"]; + yield return [MessageType.VideoNote, "video_note"]; + yield return [MessageType.Voice, "voice"]; + yield return [MessageType.Contact, "contact"]; + yield return [MessageType.Dice, "dice"]; + yield return [MessageType.Game, "game"]; + yield return [MessageType.Poll, "poll"]; + yield return [MessageType.Venue, "venue"]; + yield return [MessageType.Location, "location"]; + yield return [MessageType.NewChatMembers, "new_chat_members"]; + yield return [MessageType.LeftChatMember, "left_chat_member"]; + yield return [MessageType.NewChatTitle, "new_chat_title"]; + yield return [MessageType.NewChatPhoto, "new_chat_photo"]; + yield return [MessageType.DeleteChatPhoto, "delete_chat_photo"]; + yield return [MessageType.GroupChatCreated, "group_chat_created"]; + yield return [MessageType.SupergroupChatCreated, "supergroup_chat_created"]; + yield return [MessageType.ChannelChatCreated, "channel_chat_created"]; + yield return [MessageType.MessageAutoDeleteTimerChanged, "message_auto_delete_timer_changed"]; + yield return [MessageType.MigrateToChatId, "migrate_to_chat_id"]; + yield return [MessageType.MigrateFromChatId, "migrate_from_chat_id"]; + yield return [MessageType.PinnedMessage, "pinned_message"]; + yield return [MessageType.Invoice, "invoice"]; + yield return [MessageType.SuccessfulPayment, "successful_payment"]; + yield return [MessageType.UsersShared, "users_shared"]; + yield return [MessageType.ChatShared, "chat_shared"]; + yield return [MessageType.ConnectedWebsite, "connected_website"]; + yield return [MessageType.WriteAccessAllowed, "write_access_allowed"]; + yield return [MessageType.PassportData, "passport_data"]; + yield return [MessageType.ProximityAlertTriggered, "proximity_alert_triggered"]; + yield return [MessageType.ForumTopicCreated, "forum_topic_created"]; + yield return [MessageType.ForumTopicEdited, "forum_topic_edited"]; + yield return [MessageType.ForumTopicClosed, "forum_topic_closed"]; + yield return [MessageType.ForumTopicReopened, "forum_topic_reopened"]; + yield return [MessageType.GeneralForumTopicHidden, "general_forum_topic_hidden"]; + yield return [MessageType.GeneralForumTopicUnhidden, "general_forum_topic_unhidden"]; + yield return [MessageType.GiveawayCreated, "giveaway_created"]; + yield return [MessageType.Giveaway, "giveaway"]; + yield return [MessageType.GiveawayWinners, "giveaway_winners"]; + yield return [MessageType.GiveawayCompleted, "giveaway_completed"]; + yield return [MessageType.VideoChatScheduled, "video_chat_scheduled"]; + yield return [MessageType.VideoChatStarted, "video_chat_started"]; + yield return [MessageType.VideoChatEnded, "video_chat_ended"]; + yield return [MessageType.VideoChatParticipantsInvited, "video_chat_participants_invited"]; + yield return [MessageType.WebAppData, "web_app_data"]; } IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs index 5002f480c..68c343692 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs @@ -17,7 +17,7 @@ public void Should_Deserialize_Chat() string serializeChat = JsonConvert.SerializeObject(chat); - Assert.Contains(@"""unrestricted_boost_count"":10", serializeChat); + Assert.Contains(@"""unrestrict_boost_count"":10", serializeChat); Assert.Contains(@"""custom_emoji_sticker_set_name"":""test_sticker_set""", serializeChat); } } From 2c45e70323bec574f3d1a1e577788a1bd2aaa78e Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 00:58:40 +0400 Subject: [PATCH 56/90] Add unit tests for Chat and ChatBoostAdded --- .../ChatBoostAddedSerializationTests.cs | 38 +++++++++++++++++++ .../Serialization/ChatSerializationTests.cs | 30 +++++++++++++-- 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs new file mode 100644 index 000000000..dc3663f2d --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs @@ -0,0 +1,38 @@ +using Newtonsoft.Json; +using Telegram.Bot.Types; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.Serialization; + +public class ChatBoostAddedSerializationTests +{ + [Fact] + public void Should_Deserialize_ChatBoostAdded() + { + const string chatBoostAdded = + """ + { + "boost_count": 101 + } + """; + + ChatBoostAdded? deserialize = JsonConvert.DeserializeObject(chatBoostAdded); + + Assert.NotNull(deserialize); + Assert.Equal(101, deserialize.BoostCount); + } + + [Fact] + public void Should_Serialize_ChatBoostAdded() + { + ChatBoostAdded chat = new() + { + BoostCount = 101, + }; + + ChatBoostAdded? deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(chat)); + + Assert.NotNull(deserialized); + Assert.Equal(deserialized.BoostCount, deserialized.BoostCount); + } +} diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs index 68c343692..7b4639ab9 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs @@ -1,5 +1,6 @@ using Newtonsoft.Json; using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; using Xunit; namespace Telegram.Bot.Tests.Unit.Serialization; @@ -8,6 +9,28 @@ public class ChatSerializationTests { [Fact] public void Should_Deserialize_Chat() + { + const string chat = + """ + { + "id": 12345, + "type": "supergroup", + "unrestrict_boost_count": 10, + "custom_emoji_sticker_set_name": "test_sticker_set" + } + """; + + Chat? deserialize = JsonConvert.DeserializeObject(chat); + + Assert.NotNull(deserialize); + Assert.Equal(10, deserialize.UnrestrictBoostCount); + Assert.Equal(12345, deserialize.Id); + Assert.Equal(ChatType.Supergroup, deserialize.Type); + Assert.Equal("test_sticker_set", deserialize.CustomEmojiStickerSetName); + } + + [Fact] + public void Should_Serialize_Chat() { Chat chat = new() { @@ -15,9 +38,10 @@ public void Should_Deserialize_Chat() CustomEmojiStickerSetName = "test_sticker_set" }; - string serializeChat = JsonConvert.SerializeObject(chat); + Chat? deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(chat)); - Assert.Contains(@"""unrestrict_boost_count"":10", serializeChat); - Assert.Contains(@"""custom_emoji_sticker_set_name"":""test_sticker_set""", serializeChat); + Assert.NotNull(deserialized); + Assert.Equal(deserialized.UnrestrictBoostCount, deserialized.UnrestrictBoostCount); + Assert.Equal(chat.CustomEmojiStickerSetName, deserialized.CustomEmojiStickerSetName); } } From 32ab8fb8a5da4a76aa3b14c92408355feec25745 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 01:59:27 +0400 Subject: [PATCH 57/90] Rewrite serialization tests to use JObject for asserts --- .../ChatMemberSerializationTests.cs | 76 +++++++++-------- .../MessageOriginSerializationTests.cs | 82 +++++++++++-------- 2 files changed, 93 insertions(+), 65 deletions(-) diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs index 709e2062b..df9406325 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -62,17 +64,21 @@ public void Should_Serialize_Chat_Member_Member() CustomTitle = "Custom test title" }; - string? chatMemberJson = JsonConvert.SerializeObject(creator); - Assert.Contains(@"""status"":""creator""", chatMemberJson); - Assert.Contains(@"""is_anonymous"":true", chatMemberJson); - Assert.Contains(@"""custom_title"":""Custom test title""", chatMemberJson); - Assert.Contains(@"""user"":{", chatMemberJson); - Assert.Contains(@"""id"":12345", chatMemberJson); - Assert.Contains(@"""is_bot"":true", chatMemberJson); - Assert.Contains(@"""first_name"":""First Name""", chatMemberJson); - Assert.Contains(@"""last_name"":""Last Name""", chatMemberJson); - Assert.Contains(@"""username"":""test_bot""", chatMemberJson); - Assert.Contains(@"""language_code"":""en_US""", chatMemberJson); + string chatMemberJson = JsonConvert.SerializeObject(creator); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(4, j.Children().Count()); + Assert.Equal("creator", j["status"]); + Assert.Equal(true, j["is_anonymous"]); + Assert.Equal("Custom test title", j["custom_title"]); + Assert.True(j.ContainsKey("user")); + Assert.Equal(6, j["user"]?.Children().Count()); + Assert.Equal(12345, j["user"]?["id"]); + Assert.Equal(true, j["user"]?["is_bot"]); + Assert.Equal("First Name", j["user"]?["first_name"]); + Assert.Equal("Last Name", j["user"]?["first_name"]); + Assert.Equal("test_bot", j["user"]?["username"]); + Assert.Equal("en_US", j["user"]?["language_code"]); } [Fact] @@ -92,17 +98,20 @@ public void Should_Serialize_Chat_Member_Banned() UntilDate = new(2021, 4, 2, 0, 0, 0, DateTimeKind.Utc) }; - string? chatMemberJson = JsonConvert.SerializeObject(creator); - - Assert.Contains(@"""until_date"":1617321600", chatMemberJson); - Assert.Contains(@"""status"":""kicked""", chatMemberJson); - Assert.Contains(@"""user"":{", chatMemberJson); - Assert.Contains(@"""id"":12345", chatMemberJson); - Assert.Contains(@"""is_bot"":true", chatMemberJson); - Assert.Contains(@"""first_name"":""First Name""", chatMemberJson); - Assert.Contains(@"""last_name"":""Last Name""", chatMemberJson); - Assert.Contains(@"""username"":""test_bot""", chatMemberJson); - Assert.Contains(@"""language_code"":""en_US""", chatMemberJson); + string chatMemberJson = JsonConvert.SerializeObject(creator); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(3, j.Children().Count()); + Assert.Equal(1617321600, j["until_date"]); + Assert.Equal("kicked", j["status"]); + Assert.True(j.ContainsKey("user")); + Assert.Equal(6, j["user"]?.Children().Count()); + Assert.Equal(12345, j["user"]?["id"]); + Assert.Equal(true, j["user"]?["is_bot"]); + Assert.Equal("First Name", j["user"]?["first_name"]); + Assert.Equal("Last Name", j["user"]?["first_name"]); + Assert.Equal("test_bot", j["user"]?["username"]); + Assert.Equal("en_US", j["user"]?["language_code"]); } [Fact] @@ -122,16 +131,19 @@ public void Should_Serialize_Chat_Member_Banned_2() }; string chatMemberJson = JsonConvert.SerializeObject(creator); - - Assert.DoesNotContain(@"""until_date""", chatMemberJson); - Assert.Contains(@"""status"":""kicked""", chatMemberJson); - Assert.Contains(@"""user"":{", chatMemberJson); - Assert.Contains(@"""id"":12345", chatMemberJson); - Assert.Contains(@"""is_bot"":true", chatMemberJson); - Assert.Contains(@"""first_name"":""First Name""", chatMemberJson); - Assert.Contains(@"""last_name"":""Last Name""", chatMemberJson); - Assert.Contains(@"""username"":""test_bot""", chatMemberJson); - Assert.Contains(@"""language_code"":""en_US""", chatMemberJson); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(2, j.Children().Count()); + Assert.False(j.ContainsKey("until_date")); + Assert.Equal("kicked", j["status"]); + Assert.True(j.ContainsKey("user")); + Assert.Equal(6, j["user"]?.Children().Count()); + Assert.Equal(12345, j["user"]?["id"]); + Assert.Equal(true, j["user"]?["is_bot"]); + Assert.Equal("First Name", j["user"]?["first_name"]); + Assert.Equal("Last Name", j["user"]?["first_name"]); + Assert.Equal("test_bot", j["user"]?["username"]); + Assert.Equal("en_US", j["user"]?["language_code"]); } [Fact] diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs index e3fa62dc0..96e6cdd44 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MessageOriginSerializationTests.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -25,15 +27,22 @@ public void Should_Serialize_MessageOriginUser() Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) }; - MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( - JsonConvert.SerializeObject(origin) - ); - Assert.NotNull(messageOrigin); + string json = JsonConvert.SerializeObject(origin); + JObject j = JObject.Parse(json); + + Assert.Equal(3, j.Children().Count()); + Assert.Equal(1708106405, j["date"]); - MessageOriginUser messageOriginUser = Assert.IsType(messageOrigin); + JToken? senderUser = j["sender_user"]; + Assert.NotNull(senderUser); - Assert.Equal(origin.Date, messageOriginUser.Date); - Assert.Equal(origin.SenderUser.Id, messageOriginUser.SenderUser.Id); + Assert.Equal(6, senderUser.Children().Count()); + Assert.Equal(12345, senderUser["id"]); + Assert.Equal(true, senderUser["is_bot"]); + Assert.Equal("First Name", senderUser["first_name"]); + Assert.Equal("Last Name", senderUser["first_name"]); + Assert.Equal("test_bot", senderUser["username"]); + Assert.Equal("en_US", senderUser["language_code"]); } [Fact] @@ -45,15 +54,16 @@ public void Should_Serialize_MessageOriginHidden() Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) }; - MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( - JsonConvert.SerializeObject(origin) - ); - Assert.NotNull(messageOrigin); + string json = JsonConvert.SerializeObject(origin); + JObject j = JObject.Parse(json); + + Assert.Equal(3, j.Children().Count()); + Assert.Equal(1708106405, j["date"]); - MessageOriginHiddenUser messageOriginHiddenUser = Assert.IsType(messageOrigin); + JToken? senderUser = j["sender_user_name"]; + Assert.NotNull(senderUser); - Assert.Equal(origin.Date, messageOriginHiddenUser.Date); - Assert.Equal(origin.SenderUserName, origin.SenderUserName); + Assert.Equal("test_bot", senderUser); } [Fact] @@ -65,22 +75,26 @@ public void Should_Serialize_MessageOriginChat() { Id = 12345, Type = ChatType.Supergroup, - Username = "test_bot", + Username = "test_group", IsForum = true, }, Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) }; - MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( - JsonConvert.SerializeObject(origin) - ); - Assert.NotNull(messageOrigin); + string json = JsonConvert.SerializeObject(origin); + JObject j = JObject.Parse(json); - MessageOriginChat messageOriginChat = Assert.IsType(messageOrigin); + Assert.Equal(3, j.Children().Count()); + Assert.Equal(1708106405, j["date"]); - Assert.Equal(origin.Date, messageOriginChat.Date); - Assert.Equal(origin.SenderChat.Id, messageOriginChat.SenderChat.Id); - Assert.Equal(origin.SenderChat.Type, messageOriginChat.SenderChat.Type); + JToken? senderChat = j["sender_chat"]; + Assert.NotNull(senderChat); + + Assert.Equal(4, senderChat.Children().Count()); + Assert.Equal(12345, senderChat["id"]); + Assert.Equal("supergroup", senderChat["type"]); + Assert.Equal("test_group", senderChat["username"]); + Assert.Equal(true, senderChat["is_forum"]); } [Fact] @@ -99,19 +113,21 @@ public void Should_Serialize_MessageOriginChannel() Date = new(2024, 2, 16, 18, 0, 0, 0, DateTimeKind.Utc) }; - MessageOrigin? messageOrigin = JsonConvert.DeserializeObject( - JsonConvert.SerializeObject(origin) - ); - Assert.NotNull(messageOrigin); + string json = JsonConvert.SerializeObject(origin); + JObject j = JObject.Parse(json); - MessageOriginChannel messageOriginChat = Assert.IsType(messageOrigin); + Assert.Equal(5, j.Children().Count()); + Assert.Equal(1708106405, j["date"]); + Assert.Equal(1236886, j["message_id"]); + Assert.Equal("author_name", j["author_signature"]); - Assert.Equal(origin.Date, messageOriginChat.Date); - Assert.Equal(origin.Chat.Id, messageOriginChat.Chat.Id); - Assert.Equal(origin.Chat.Type, messageOriginChat.Chat.Type); - Assert.Equal(origin.AuthorSignature, messageOriginChat.AuthorSignature); - Assert.Equal(origin.MessageId, messageOriginChat.MessageId); + JToken? chat = j["chat"]; + Assert.NotNull(chat); + Assert.Equal(3, chat.Children().Count()); + Assert.Equal(12345, chat["id"]); + Assert.Equal("supergroup", chat["type"]); + Assert.Equal("test_group", chat["username"]); } [Fact] From cce06b7be2acf49b55b37a64a659b9f7c24678b9 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 02:01:06 +0400 Subject: [PATCH 58/90] Add XML documentation for MessageOriginType --- src/Telegram.Bot/Types/Enums/MenuButtonType.cs | 2 +- src/Telegram.Bot/Types/Enums/MessageOriginType.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Telegram.Bot/Types/Enums/MenuButtonType.cs b/src/Telegram.Bot/Types/Enums/MenuButtonType.cs index a3d26e94c..0e0d309d4 100644 --- a/src/Telegram.Bot/Types/Enums/MenuButtonType.cs +++ b/src/Telegram.Bot/Types/Enums/MenuButtonType.cs @@ -19,5 +19,5 @@ public enum MenuButtonType /// /// Represents a menu button, which launches a Web App. /// - WebApp + WebApp, } diff --git a/src/Telegram.Bot/Types/Enums/MessageOriginType.cs b/src/Telegram.Bot/Types/Enums/MessageOriginType.cs index c57d5f7d8..ee7b834e6 100644 --- a/src/Telegram.Bot/Types/Enums/MessageOriginType.cs +++ b/src/Telegram.Bot/Types/Enums/MessageOriginType.cs @@ -7,22 +7,22 @@ public enum MessageOriginType { /// - /// + /// Message origin is from a user /// User = 1, /// - /// + /// Message origin is from a hidden user /// HiddenUser, /// - /// + /// Message origin is a chat /// Chat, /// - /// + /// Message origin is a channel /// Channel, } From bef3a2dc9902eac424325841b7bdb014c5ce9050 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 02:30:30 +0400 Subject: [PATCH 59/90] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0096f32f..0df125f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -120,7 +120,7 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Replaced the property `UserShared` in the class Message with the property `UsersShared`. - Replaced enum member `MessageType.UserShared` with `MessageType.UsersShared` - Fields `ForwardFrom`, `ForwardFromChat`, `ForwardFromMessageId`, `ForwardSignature`, `ForwardSenderName` -and `ForwardDate` with the field `ForwardOrigin` of type `MessageOrigin` in the class `Message`. +and `ForwardDate` replaced with the field `ForwardOrigin` of type `MessageOrigin` in the class `Message`. - Type of the property `Message` of the class `CallbackQuery` to `MaybeInaccessibleMessage` - Type of the property `PinnedMessage` of the class `Message` to `MaybeInaccessibleMessage`. From 54fb47379fa68139f3687b8d1e34420cea2306d0 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 02:59:14 +0400 Subject: [PATCH 60/90] Refactor some serialization unit tests to use JObject --- .../ChatBoostAddedSerializationTests.cs | 8 ++-- .../Serialization/ChatSerializationTests.cs | 18 +++++--- .../InputFileSerializationTests.cs | 30 ++++--------- .../Serialization/InputQueryResultTests.cs | 44 +++++++++++++++---- 4 files changed, 63 insertions(+), 37 deletions(-) diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs index dc3663f2d..d0620d831 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatBoostAddedSerializationTests.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Xunit; @@ -30,9 +31,10 @@ public void Should_Serialize_ChatBoostAdded() BoostCount = 101, }; - ChatBoostAdded? deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(chat)); + string json = JsonConvert.SerializeObject(chat); + JObject j = JObject.Parse(json); - Assert.NotNull(deserialized); - Assert.Equal(deserialized.BoostCount, deserialized.BoostCount); + Assert.Single(j.Children()); + Assert.Equal(101, j["boost_count"]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs index 7b4639ab9..7b4d330bf 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSerializationTests.cs @@ -1,4 +1,6 @@ -using Newtonsoft.Json; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -34,14 +36,20 @@ public void Should_Serialize_Chat() { Chat chat = new() { + Id = 1000, + Type = ChatType.Supergroup, UnrestrictBoostCount = 10, CustomEmojiStickerSetName = "test_sticker_set" }; - Chat? deserialized = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(chat)); + string json = JsonConvert.SerializeObject(chat); - Assert.NotNull(deserialized); - Assert.Equal(deserialized.UnrestrictBoostCount, deserialized.UnrestrictBoostCount); - Assert.Equal(chat.CustomEmojiStickerSetName, deserialized.CustomEmojiStickerSetName); + JObject j = JObject.Parse(json); + + Assert.Equal(4, j.Children().Count()); + Assert.Equal(chat.UnrestrictBoostCount, j["unrestrict_boost_count"]); + Assert.Equal("supergroup", j["type"]); + Assert.Equal(chat.Id, j["id"]); + Assert.Equal(chat.CustomEmojiStickerSetName, j["custom_emoji_sticker_set_name"]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/InputFileSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/InputFileSerializationTests.cs index fe5ff997a..e33a19586 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/InputFileSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/InputFileSerializationTests.cs @@ -2,7 +2,6 @@ using System.IO; using Newtonsoft.Json; using Telegram.Bot.Types; -using Telegram.Bot.Types.Enums; using Xunit; namespace Telegram.Bot.Tests.Unit.Serialization; @@ -13,15 +12,12 @@ public class InputFileSerializationTests public void Should_Serialize_InputFile() { const string fileName = "myFile"; - InputFileStream inputFile = new(new MemoryStream(), fileName); + using MemoryStream memoryStream = new(); + InputFileStream inputFile = new(memoryStream, fileName); - string json = JsonConvert.SerializeObject(inputFile); - InputFileStream obj = JsonConvert.DeserializeObject(json)!; + string serializedValue = JsonConvert.SerializeObject(inputFile); - Assert.Equal(@$"""attach://{fileName}""", json); - Assert.Equal(Stream.Null, obj.Content); - Assert.Equal(fileName, obj.FileName); - Assert.Equal(FileType.Stream, obj.FileType); + Assert.Equal(@$"""attach://{fileName}""", serializedValue); } [Fact(DisplayName = "Should serialize & deserialize input file with file_id")] @@ -30,27 +26,19 @@ public void Should_Serialize_FileId() const string fileId = "This-is-a-file_id"; InputFileId inputFileId = new(fileId); - string json = JsonConvert.SerializeObject(inputFileId); - InputFileId? obj = JsonConvert.DeserializeObject(json); + string serializedValue = JsonConvert.SerializeObject(inputFileId); - Assert.NotNull(obj); - Assert.Equal(@$"""{fileId}""", json); - Assert.Equal(fileId, obj.Id); - Assert.Equal(FileType.Id, obj.FileType); + Assert.Equal($"\"{fileId}\"", serializedValue); } [Fact(DisplayName = "Should serialize & deserialize input file with URL")] public void Should_Serialize_InputUrlFile() { - Uri url = new("http://github.org/TelegramBots"); + Uri url = new("https://github.com/TelegramBots"); InputFileUrl inputFileUrl = new(url); - string json = JsonConvert.SerializeObject(inputFileUrl); - InputFileUrl? obj = JsonConvert.DeserializeObject(json); + string serializedValue = JsonConvert.SerializeObject(inputFileUrl); - Assert.NotNull(obj); - Assert.Equal(@$"""{url}""", json); - Assert.Equal(url, obj.Url); - Assert.Equal(FileType.Url, obj.FileType); + Assert.Equal($"\"{url}\"", serializedValue); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/InputQueryResultTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/InputQueryResultTests.cs index 9c011b76c..20abec4f6 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/InputQueryResultTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/InputQueryResultTests.cs @@ -1,4 +1,6 @@ +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Requests; using Telegram.Bot.Types.InlineQueryResults; using Xunit; @@ -11,7 +13,7 @@ public class InputQueryResultTests public void Should_Serialize_InlineQueryResultMpeg4Gif_With_ThumbMimeType() { InlineQueryResult[] results = - { + [ new InlineQueryResultMpeg4Gif( id: "mpeg4_gif_result_with_video_thumb", mpeg4Url: "https://pixabay.com/en/videos/download/video-14205_tiny.mp4", @@ -19,19 +21,32 @@ public void Should_Serialize_InlineQueryResultMpeg4Gif_With_ThumbMimeType() { Caption = "A frozing bubble", ThumbnailMimeType = "video/mp4" - }, - }; + } + ]; AnswerInlineQueryRequest request = new("query_id", results) { CacheTime = 0 }; string json = JsonConvert.SerializeObject(request); - Assert.Contains(@"""thumbnail_mime_type"":""video/mp4""", json); + JObject j = JObject.Parse(json); + Assert.Equal(3, j.Children().Count()); + Assert.Equal("query_id", j["inline_query_id"]); + Assert.Equal(0, j["cache_time"]); + + JArray ja = Assert.IsType(j["results"]); + Assert.Single(ja); + + JToken element = ja[0]; + Assert.Equal("video/mp4", element["thumbnail_mime_type"]); + Assert.Equal("gif_result_with_video_thumb", element["id"]); + Assert.Equal("A frozing bubble", element["caption"]); + Assert.Equal("https://pixabay.com/en/videos/download/video-14205_tiny.mp4", element["mpeg4_url"]); + Assert.Equal("https://pixabay.com/en/videos/download/video-14205_tiny.mp4", element["thumbnail_url"]); } [Fact(DisplayName = "Should serialize InlineQueryResultGif with ThumbMimeType")] public void Should_Serialize_InlineQueryResultGif_With_ThumbMimeType() { InlineQueryResult[] results = - { + [ new InlineQueryResultGif( id: "gif_result_with_video_thumb", gifUrl: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif", @@ -39,12 +54,25 @@ public void Should_Serialize_InlineQueryResultGif_With_ThumbMimeType() { Caption = "A frozing bubble", ThumbnailMimeType = "video/mp4" - }, - }; + } + ]; AnswerInlineQueryRequest request = new("query_id", results) { CacheTime = 0 }; string json = JsonConvert.SerializeObject(request); - Assert.Contains(@"""thumbnail_mime_type"":""video/mp4""", json); + JObject j = JObject.Parse(json); + Assert.Equal(3, j.Children().Count()); + Assert.Equal("query_id", j["inline_query_id"]); + Assert.Equal(0, j["cache_time"]); + + JArray ja = Assert.IsType(j["results"]); + Assert.Single(ja); + + JToken element = ja[0]; + Assert.Equal("video/mp4", element["thumbnail_mime_type"]); + Assert.Equal("gif_result_with_video_thumb", element["id"]); + Assert.Equal("A frozing bubble", element["caption"]); + Assert.Equal("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif", element["gif_url"]); + Assert.Equal("https://pixabay.com/en/videos/download/video-14205_tiny.mp4", element["thumbnail_url"]); } } From 60d18df87b7ff6463bebfdebdfae18a109e92b85 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:10:05 +0400 Subject: [PATCH 61/90] Fix XML docs line length --- src/Telegram.Bot/Types/CallbackGame.cs | 4 +--- src/Telegram.Bot/Types/ForumTopicClosed.cs | 2 +- src/Telegram.Bot/Types/ForumTopicReopened.cs | 2 +- src/Telegram.Bot/Types/GeneralForumTopicHidden.cs | 2 +- src/Telegram.Bot/Types/GeneralForumTopicUnhidden.cs | 2 +- src/Telegram.Bot/Types/GiveawayCreated.cs | 4 +--- .../InputMessageContent/InputMessageContent.cs | 2 +- .../Types/InputFiles/InputMedia/IAlbumInputMedia.cs | 3 +-- src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs | 4 +--- src/Telegram.Bot/Types/ReplyMarkups/IReplyMarkup.cs | 4 +--- src/Telegram.Bot/Types/ReplyParameters.cs | 3 ++- src/Telegram.Bot/Types/Update.cs | 6 ++++-- src/Telegram.Bot/Types/User.cs | 9 ++++++--- src/Telegram.Bot/Types/VideoChatStarted.cs | 3 +-- src/Telegram.Bot/Types/WriteAccessAllowed.cs | 9 ++++++--- 15 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/Telegram.Bot/Types/CallbackGame.cs b/src/Telegram.Bot/Types/CallbackGame.cs index 193ecc905..6b01d1cba 100644 --- a/src/Telegram.Bot/Types/CallbackGame.cs +++ b/src/Telegram.Bot/Types/CallbackGame.cs @@ -5,6 +5,4 @@ namespace Telegram.Bot.Types; /// to set up your game. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class CallbackGame -{ -} +public class CallbackGame; diff --git a/src/Telegram.Bot/Types/ForumTopicClosed.cs b/src/Telegram.Bot/Types/ForumTopicClosed.cs index 71d3548e2..410afffc8 100644 --- a/src/Telegram.Bot/Types/ForumTopicClosed.cs +++ b/src/Telegram.Bot/Types/ForumTopicClosed.cs @@ -4,4 +4,4 @@ namespace Telegram.Bot.Types; /// This object represents a service message about a forum topic closed in the chat. Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class ForumTopicClosed { } +public class ForumTopicClosed; diff --git a/src/Telegram.Bot/Types/ForumTopicReopened.cs b/src/Telegram.Bot/Types/ForumTopicReopened.cs index 8b9f0b120..f6beac7c4 100644 --- a/src/Telegram.Bot/Types/ForumTopicReopened.cs +++ b/src/Telegram.Bot/Types/ForumTopicReopened.cs @@ -4,4 +4,4 @@ namespace Telegram.Bot.Types; /// This object represents a service message about a forum topic reopened in the chat. Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class ForumTopicReopened { } +public class ForumTopicReopened; diff --git a/src/Telegram.Bot/Types/GeneralForumTopicHidden.cs b/src/Telegram.Bot/Types/GeneralForumTopicHidden.cs index 2aea8eaf1..cd2e1023f 100644 --- a/src/Telegram.Bot/Types/GeneralForumTopicHidden.cs +++ b/src/Telegram.Bot/Types/GeneralForumTopicHidden.cs @@ -5,4 +5,4 @@ namespace Telegram.Bot.Types; /// Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class GeneralForumTopicHidden { } +public class GeneralForumTopicHidden; diff --git a/src/Telegram.Bot/Types/GeneralForumTopicUnhidden.cs b/src/Telegram.Bot/Types/GeneralForumTopicUnhidden.cs index 6c765f321..e8c63cf6b 100644 --- a/src/Telegram.Bot/Types/GeneralForumTopicUnhidden.cs +++ b/src/Telegram.Bot/Types/GeneralForumTopicUnhidden.cs @@ -5,4 +5,4 @@ namespace Telegram.Bot.Types; /// Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class GeneralForumTopicUnhidden { } +public class GeneralForumTopicUnhidden; diff --git a/src/Telegram.Bot/Types/GiveawayCreated.cs b/src/Telegram.Bot/Types/GiveawayCreated.cs index 1bf8aecbd..dcf66f328 100644 --- a/src/Telegram.Bot/Types/GiveawayCreated.cs +++ b/src/Telegram.Bot/Types/GiveawayCreated.cs @@ -5,6 +5,4 @@ namespace Telegram.Bot.Types; /// Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class GiveawayCreated -{ -} +public class GiveawayCreated; diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs index ddf99ad34..5d5871d3b 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs @@ -8,4 +8,4 @@ namespace Telegram.Bot.Types.InlineQueryResults; /// inline query. /// [JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public abstract class InputMessageContent { } +public abstract class InputMessageContent; diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/IAlbumInputMedia.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/IAlbumInputMedia.cs index 4dc00df7d..232bccaf6 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/IAlbumInputMedia.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/IAlbumInputMedia.cs @@ -4,5 +4,4 @@ namespace Telegram.Bot.Types; /// /// A marker for input media types that can be used in sendMediaGroup method. /// -public interface IAlbumInputMedia -{ } +public interface IAlbumInputMedia; diff --git a/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs index 93b14b2aa..2eaeb4c58 100644 --- a/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs +++ b/src/Telegram.Bot/Types/MaybeInaccessibleMessage.cs @@ -11,6 +11,4 @@ namespace Telegram.Bot.Types; /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] [JsonConverter(typeof(MaybeInaccessibleMessageConverter))] -public abstract class MaybeInaccessibleMessage -{ -} +public abstract class MaybeInaccessibleMessage; diff --git a/src/Telegram.Bot/Types/ReplyMarkups/IReplyMarkup.cs b/src/Telegram.Bot/Types/ReplyMarkups/IReplyMarkup.cs index 360d16d55..164df00d1 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/IReplyMarkup.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/IReplyMarkup.cs @@ -3,6 +3,4 @@ /// /// A marker interface for reply markups that define how a can reply to the sent /// -public interface IReplyMarkup -{ -} \ No newline at end of file +public interface IReplyMarkup; \ No newline at end of file diff --git a/src/Telegram.Bot/Types/ReplyParameters.cs b/src/Telegram.Bot/Types/ReplyParameters.cs index 8c242f6ec..cca410128 100644 --- a/src/Telegram.Bot/Types/ReplyParameters.cs +++ b/src/Telegram.Bot/Types/ReplyParameters.cs @@ -7,7 +7,8 @@ namespace Telegram.Bot.Types; public class ReplyParameters { /// - /// Identifier of the message that will be replied to in the current chat, or in the chat if it is specified + /// Identifier of the message that will be replied to in the current chat, + /// or in the chat if it is specified /// [JsonProperty(Required = Required.Always)] public int MessageId { get; set; } diff --git a/src/Telegram.Bot/Types/Update.cs b/src/Telegram.Bot/Types/Update.cs index 6ca576a86..d314cd6fe 100644 --- a/src/Telegram.Bot/Types/Update.cs +++ b/src/Telegram.Bot/Types/Update.cs @@ -129,13 +129,15 @@ public class Update public ChatJoinRequest? ChatJoinRequest { get; set; } /// - /// Optional. A chat boost was added or changed. The bot must be an administrator in the chat to receive these updates. + /// Optional. A chat boost was added or changed. + /// The bot must be an administrator in the chat to receive these updates. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public ChatBoostUpdated? ChatBoost { get; set; } /// - /// Optional. A boost was removed from a chat. The bot must be an administrator in the chat to receive these updates. + /// Optional. A boost was removed from a chat. + /// The bot must be an administrator in the chat to receive these updates. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public ChatBoostRemoved? RemovedChatBoost { get; set; } diff --git a/src/Telegram.Bot/Types/User.cs b/src/Telegram.Bot/Types/User.cs index 7eb768af0..d1866cbdf 100644 --- a/src/Telegram.Bot/Types/User.cs +++ b/src/Telegram.Bot/Types/User.cs @@ -56,19 +56,22 @@ public class User public bool? AddedToAttachmentMenu { get; set; } /// - /// Optional. , if the bot can be invited to groups. Returned only in + /// Optional. , if the bot can be invited to groups. + /// Returned only in /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? CanJoinGroups { get; set; } /// - /// Optional. , if privacy mode is disabled for the bot. Returned only in + /// Optional. , if privacy mode is disabled for the bot. + /// Returned only in /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? CanReadAllGroupMessages { get; set; } /// - /// Optional. , if the bot supports inline queries. Returned only in + /// Optional. , if the bot supports inline queries. + /// Returned only in /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? SupportsInlineQueries { get; set; } diff --git a/src/Telegram.Bot/Types/VideoChatStarted.cs b/src/Telegram.Bot/Types/VideoChatStarted.cs index b05adecf8..e94263d3c 100644 --- a/src/Telegram.Bot/Types/VideoChatStarted.cs +++ b/src/Telegram.Bot/Types/VideoChatStarted.cs @@ -4,5 +4,4 @@ /// This object represents a service message about a video chat started in the chat. Currently holds no information. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class VideoChatStarted -{ } +public class VideoChatStarted; diff --git a/src/Telegram.Bot/Types/WriteAccessAllowed.cs b/src/Telegram.Bot/Types/WriteAccessAllowed.cs index 7036bd773..bd021fdb5 100644 --- a/src/Telegram.Bot/Types/WriteAccessAllowed.cs +++ b/src/Telegram.Bot/Types/WriteAccessAllowed.cs @@ -3,14 +3,16 @@ namespace Telegram.Bot.Types; /// /// This object represents a service message about a user allowing a bot to write messages after adding /// it to the attachment menu, launching a Web App from a link, or accepting an explicit request from -/// a Web App sent by the method requestWriteAccess. +/// a Web App sent by the method +/// requestWriteAccess. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class WriteAccessAllowed { /// /// Optional. , if the access was granted after the user accepted an explicit request - /// from a Web App sent by the method requestWriteAccess + /// from a Web App sent by the method + /// requestWriteAccess /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? FromRequest { get; set; } @@ -22,7 +24,8 @@ public class WriteAccessAllowed public string? WebAppName { get; set; } /// - /// Optional. , if the access was granted when the bot was added to the attachment or side menu + /// Optional. , if the access was granted when the bot was added to the attachment + /// or side menu /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? FromAttachmentMenu { get; set; } From 473dc95dea8ec7456860d4e8a3d1f6ff53b6dab2 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:10:30 +0400 Subject: [PATCH 62/90] Make a property public on a public API type --- src/Telegram.Bot/Types/UserChatBoosts.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Telegram.Bot/Types/UserChatBoosts.cs b/src/Telegram.Bot/Types/UserChatBoosts.cs index b0bdeca54..4463eb334 100644 --- a/src/Telegram.Bot/Types/UserChatBoosts.cs +++ b/src/Telegram.Bot/Types/UserChatBoosts.cs @@ -12,5 +12,5 @@ public class UserChatBoosts /// The list of boosts added to the chat by the user /// [JsonProperty(Required = Required.Always)] - IEnumerable Boosts { get; set; } = default!; + public IEnumerable Boosts { get; set; } = default!; } From 27ab6e092ae7ee9b392f97861fa10a493b256404 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:10:55 +0400 Subject: [PATCH 63/90] Make reaction type property an enum for consistency --- .../Types/Enums/ReactionTypeKind.cs | 18 ++++++ src/Telegram.Bot/Types/ReactionType.cs | 7 ++- .../ReactionTypeKindConverterTests.cs | 63 +++++++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/Telegram.Bot/Types/Enums/ReactionTypeKind.cs create mode 100644 test/Telegram.Bot.Tests.Unit/EnumConverter/ReactionTypeKindConverterTests.cs diff --git a/src/Telegram.Bot/Types/Enums/ReactionTypeKind.cs b/src/Telegram.Bot/Types/Enums/ReactionTypeKind.cs new file mode 100644 index 000000000..9ba85a676 --- /dev/null +++ b/src/Telegram.Bot/Types/Enums/ReactionTypeKind.cs @@ -0,0 +1,18 @@ +namespace Telegram.Bot.Types.Enums; + +/// +/// Type of the reaction +/// +[JsonConverter(typeof(ReactionTypeKindConverter))] +public enum ReactionTypeKind +{ + /// + /// The reaction is based on an emoji. + /// + Emoji = 1, + + /// + /// The reaction is based on a custom emoji. + /// + CustomEmoji, +} diff --git a/src/Telegram.Bot/Types/ReactionType.cs b/src/Telegram.Bot/Types/ReactionType.cs index 396ede22e..1f3fa8023 100644 --- a/src/Telegram.Bot/Types/ReactionType.cs +++ b/src/Telegram.Bot/Types/ReactionType.cs @@ -1,4 +1,5 @@ using Telegram.Bot.Converters; +using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Types; @@ -17,7 +18,7 @@ public abstract class ReactionType /// Type of the reaction /// [JsonProperty] - public abstract string Type { get; } + public abstract ReactionTypeKind Type { get; } } /// @@ -29,7 +30,7 @@ public class ReactionTypeEmoji : ReactionType /// /// Type of the reaction, always "emoji" /// - public override string Type => "emoji"; + public override ReactionTypeKind Type => ReactionTypeKind.Emoji; /// /// Reaction emoji. Currently, it can be one of "👍", "👎", "❤", "🔥", "🥰", "👏", "😁", @@ -55,7 +56,7 @@ public class ReactionTypeCustomEmoji : ReactionType /// /// Type of the reaction, always "custom_emoji" /// - public override string Type => "custom_emoji"; + public override ReactionTypeKind Type => ReactionTypeKind.CustomEmoji; /// /// Custom emoji identifier diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/ReactionTypeKindConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/ReactionTypeKindConverterTests.cs new file mode 100644 index 000000000..7a650e1c2 --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/ReactionTypeKindConverterTests.cs @@ -0,0 +1,63 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.EnumConverter; + +public class ReactionTypeKindConverterTests +{ + [Theory] + [InlineData(ReactionTypeKind.Emoji, "emoji")] + [InlineData(ReactionTypeKind.CustomEmoji, "custom_emoji")] + public void Should_Convert_ChatAction_To_String(ReactionTypeKind kind, string value) + { + Container container = new() { Type = kind }; + string expectedResult = @$"{{""type"":""{value}""}}"; + + string result = JsonConvert.SerializeObject(container); + + Assert.Equal(expectedResult, result); + } + + [Theory] + [InlineData(ReactionTypeKind.Emoji, "emoji")] + [InlineData(ReactionTypeKind.CustomEmoji, "custom_emoji")] + public void Should_Convert_String_ToChatAction(ReactionTypeKind kind, string value) + { + Container expectedResult = new() { Type = kind }; + string jsonData = @$"{{""type"":""{value}""}}"; + + Container? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal(expectedResult.Type, result.Type); + } + + [Fact] + public void Should_Return_Zero_For_Incorrect_ChatAction() + { + string jsonData = @$"{{""type"":""{int.MaxValue}""}}"; + + Container? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal((ReactionTypeKind)0, result.Type); + } + + [Fact] + public void Should_Throw_NotSupportedException_For_Incorrect_ChatAction() + { + Container container = new() { Type = (ReactionTypeKind)int.MaxValue }; + + Assert.Throws(() => JsonConvert.SerializeObject(container)); + } + + [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] + class Container + { + [JsonProperty(Required = Required.Always)] + public ReactionTypeKind Type { get; init; } + } +} From 30b937a34d9f1ea0a7f69249d08e9a04e2265dfe Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:11:36 +0400 Subject: [PATCH 64/90] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0df125f85..dc61bd8d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ### Added - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. +- Enum `ReactionTypeKind` - The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. - Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. From 11e0d7010c0c549d4557172beaf3a8082b79c644 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:43:04 +0400 Subject: [PATCH 65/90] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b65d38ad..8ebc3ade9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # .NET Client for Telegram Bot API [![package](https://img.shields.io/nuget/vpre/Telegram.Bot.svg?label=Telegram.Bot&style=flat-square)](https://www.nuget.org/packages/Telegram.Bot) -[![Bot API Version](https://img.shields.io/badge/Bot%20API-7.0%20(December%2029,%202023)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#december-29-2023) +[![Bot API Version](https://img.shields.io/badge/Bot%20API-7.1%20(February%2016,%202024)-f36caf.svg?style=flat-square)](https://core.telegram.org/bots/api#february-16-2024) [![documentations](https://img.shields.io/badge/Documentations-Book-orange.svg?style=flat-square)](https://telegrambots.github.io/book/) [![telegram chat](https://img.shields.io/badge/Support_Chat-Telegram-blue.svg?style=flat-square)](https://t.me/joinchat/B35YY0QbLfd034CFnvCtCA) From 306fa3d562ee114d4e9e91abb9ed0d40f51a6c37 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 03:57:15 +0400 Subject: [PATCH 66/90] Update dependencies --- .../EnumSerializer.Generator.csproj | 4 ++-- src/Telegram.Bot/Telegram.Bot.csproj | 2 +- .../Telegram.Bot.Tests.Integ.csproj | 8 ++++---- .../Telegram.Bot.Tests.Unit.csproj | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj b/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj index 3d7760956..d4d409290 100644 --- a/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj +++ b/src/EnumSerializer.Generator/EnumSerializer.Generator.csproj @@ -14,10 +14,10 @@ - + - + diff --git a/src/Telegram.Bot/Telegram.Bot.csproj b/src/Telegram.Bot/Telegram.Bot.csproj index 5f0458a0c..8fbe478f8 100644 --- a/src/Telegram.Bot/Telegram.Bot.csproj +++ b/src/Telegram.Bot/Telegram.Bot.csproj @@ -83,7 +83,7 @@ - + diff --git a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj index 9823a6319..35477cad4 100644 --- a/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj +++ b/test/Telegram.Bot.Tests.Integ/Telegram.Bot.Tests.Integ.csproj @@ -14,10 +14,10 @@ - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj index 02d46eba5..549c13db8 100644 --- a/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj +++ b/test/Telegram.Bot.Tests.Unit/Telegram.Bot.Tests.Unit.csproj @@ -6,10 +6,10 @@ false - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive From 94c86d7cdbd1812a85c726d5b915872dc9ffe900 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 04:01:11 +0400 Subject: [PATCH 67/90] Fix devcontainer configuration --- .devcontainer/devcontainer.json | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a79f624d2..4df9724fa 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -4,14 +4,18 @@ "service": "devhost", "shutdownAction": "stopCompose", "workspaceFolder": "/workspace", - "extensions": [ - "ms-dotnettools.csharp", - "ms-azuretools.vscode-docker", - "editorconfig.editorconfig", - "eamodio.gitlens", - "tintoy.msbuild-project-tools", - "logerfo.sln-support", - "formulahendry.dotnet-test-explorer" - ], + "customizations": { + "vscode": { + "extensions": [ + "ms-dotnettools.csharp", + "ms-azuretools.vscode-docker", + "editorconfig.editorconfig", + "eamodio.gitlens", + "tintoy.msbuild-project-tools", + "logerfo.sln-support", + "formulahendry.dotnet-test-explorer" + ] + } + }, "remoteUser": "vscode" } From d61379ad5977bc5a327a9abba8a582e1f29c6ce7 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 17 Feb 2024 04:04:07 +0400 Subject: [PATCH 68/90] Replace C# extension to C# Dev Kit in devcontainer --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4df9724fa..e88852588 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,7 +7,7 @@ "customizations": { "vscode": { "extensions": [ - "ms-dotnettools.csharp", + "ms-dotnettools.csdevkit", "ms-azuretools.vscode-docker", "editorconfig.editorconfig", "eamodio.gitlens", From d8faafd736322bc7536088c1f280ba9f968fc7a6 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Tue, 20 Feb 2024 01:22:56 +0400 Subject: [PATCH 69/90] Change dev container --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 218ce4781..676357a4d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,5 @@ ARG DOTNET_VERSION=8.0 -FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bullseye-slim +FROM mcr.microsoft.com/dotnet/sdk:${DOTNET_VERSION}-bookworm-slim ARG USERNAME=vscode ARG USER_UID=1000 ARG USER_GID=${USER_UID} From 7a15cf7f9b0859c10d617d5a5db1562af91ad358 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 00:33:08 +0400 Subject: [PATCH 70/90] Use JObject API in the rest of the serialization unit tests --- .../ChatMemberSerializationTests.cs | 56 ++++++++------- .../DocumentSerializationTests.cs | 38 ++++++++-- .../InputStickerSerializationTests.cs | 63 +++++++++-------- .../MenuButtonSerializationTests.cs | 50 +++++++++----- .../Serialization/MessageEntityTests.cs | 24 ++++--- .../Serialization/MethodNameTests.cs | 34 +++++++-- .../PhotoMessageSerializationTests.cs | 69 +++++++++++++++---- .../ReplyMarkupSerializationTests.cs | 34 +++++++-- .../RequestSerializationTests.cs | 34 +++++---- .../Serialization/StorySerializationTests.cs | 23 +++++-- 10 files changed, 294 insertions(+), 131 deletions(-) diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs index df9406325..12af9f664 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs @@ -71,14 +71,17 @@ public void Should_Serialize_Chat_Member_Member() Assert.Equal("creator", j["status"]); Assert.Equal(true, j["is_anonymous"]); Assert.Equal("Custom test title", j["custom_title"]); - Assert.True(j.ContainsKey("user")); - Assert.Equal(6, j["user"]?.Children().Count()); - Assert.Equal(12345, j["user"]?["id"]); - Assert.Equal(true, j["user"]?["is_bot"]); - Assert.Equal("First Name", j["user"]?["first_name"]); - Assert.Equal("Last Name", j["user"]?["first_name"]); - Assert.Equal("test_bot", j["user"]?["username"]); - Assert.Equal("en_US", j["user"]?["language_code"]); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); } [Fact] @@ -105,13 +108,17 @@ public void Should_Serialize_Chat_Member_Banned() Assert.Equal(1617321600, j["until_date"]); Assert.Equal("kicked", j["status"]); Assert.True(j.ContainsKey("user")); - Assert.Equal(6, j["user"]?.Children().Count()); - Assert.Equal(12345, j["user"]?["id"]); - Assert.Equal(true, j["user"]?["is_bot"]); - Assert.Equal("First Name", j["user"]?["first_name"]); - Assert.Equal("Last Name", j["user"]?["first_name"]); - Assert.Equal("test_bot", j["user"]?["username"]); - Assert.Equal("en_US", j["user"]?["language_code"]); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); } [Fact] @@ -136,14 +143,17 @@ public void Should_Serialize_Chat_Member_Banned_2() Assert.Equal(2, j.Children().Count()); Assert.False(j.ContainsKey("until_date")); Assert.Equal("kicked", j["status"]); - Assert.True(j.ContainsKey("user")); - Assert.Equal(6, j["user"]?.Children().Count()); - Assert.Equal(12345, j["user"]?["id"]); - Assert.Equal(true, j["user"]?["is_bot"]); - Assert.Equal("First Name", j["user"]?["first_name"]); - Assert.Equal("Last Name", j["user"]?["first_name"]); - Assert.Equal("test_bot", j["user"]?["username"]); - Assert.Equal("en_US", j["user"]?["language_code"]); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); } [Fact] diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/DocumentSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/DocumentSerializationTests.cs index b787064b1..ec7e2ee15 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/DocumentSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/DocumentSerializationTests.cs @@ -1,5 +1,7 @@ using System; +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -35,16 +37,44 @@ public void Should_Serialize_DocumentMessage() FileSize = 123_456, MimeType = "plain/text" }, - Date = DateTime.UtcNow, + Date = new(2024, 1, 1, 10, 0, 0, DateTimeKind.Utc), Caption = "Test Document Description" }; string json = JsonConvert.SerializeObject(documentMessage); Assert.NotNull(json); - Assert.True(json.Length > 100); - Assert.Contains(@"""file_id"":""KLAHCVUydfS_jHIBildtwpmvxZg""", json); - Assert.Contains(@"""can_set_sticker_set"":true", json); + + JObject j = JObject.Parse(json); + Assert.Equal(6, j.Children().Count()); + Assert.Equal(1234, j["message_id"]); + Assert.Equal("Test Document Description", j["caption"]); + Assert.Equal(1704088800, j["date"]); + + JToken? document = j["document"]; + Assert.NotNull(document); + Assert.Equal(5, document.Children().Count()); + Assert.Equal("KLAHCVUydfS_jHIBildtwpmvxZg", document["file_id"]); + Assert.Equal("AgADcOsAAhUdZAc", document["file_unique_id"]); + Assert.Equal("test_file.txt", document["file_name"]); + Assert.Equal(123_456, document["file_size"]); + Assert.Equal("plain/text", document["mime_type"]); + + JToken? user = j["from"]; + Assert.NotNull(user); + Assert.Equal(4, user.Children().Count()); + Assert.Equal(123_456_789, user["id"]); + Assert.Equal("TelegramBots", user["first_name"]); + Assert.Equal("Telegram_Bots", user["username"]); + Assert.Equal(false, user["is_bot"]); + + JToken? chat = j["chat"]; + Assert.NotNull(chat); + Assert.Equal(4, chat.Children().Count()); + Assert.Equal(-9_877_654_320_000, chat["id"]); + Assert.Equal("Test Chat", chat["title"]); + Assert.Equal("supergroup", chat["type"]); + Assert.Equal(true, chat["can_set_sticker_set"]); } [Fact(DisplayName = "Should deserialize a document message")] diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/InputStickerSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/InputStickerSerializationTests.cs index 41cb35e86..469fff2ad 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/InputStickerSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/InputStickerSerializationTests.cs @@ -1,6 +1,8 @@ using System; using System.IO; +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -14,19 +16,21 @@ public void Should_Serialize_InputFile() { const string fileName = "myFile"; InputFileStream inputFile = new(new MemoryStream(), fileName); - string[] emojiList = { "🙂" }; + string[] emojiList = ["🙂"]; InputSticker inputSticker = new(inputFile, emojiList); string json = JsonConvert.SerializeObject(inputSticker); - InputSticker obj = JsonConvert.DeserializeObject(json)!; + JObject j = JObject.Parse(json); - InputFileStream objInputFile = (InputFileStream)obj.Sticker; + Assert.Equal(2, j.Children().Count()); + Assert.Equal($"attach://{fileName}", j["sticker"]); - Assert.Equal(emojiList, obj.EmojiList); - Assert.Contains(@$"""sticker"":""attach://{fileName}""", json); - Assert.Equal(Stream.Null, objInputFile.Content); - Assert.Equal(fileName, objInputFile.FileName); - Assert.Equal(FileType.Stream, objInputFile.FileType); + JToken? je = j["emoji_list"]; + Assert.NotNull(je); + + JArray jEmojiList = Assert.IsType(je); + Assert.Single(jEmojiList); + Assert.Equal("🙂", jEmojiList[0]); } [Fact(DisplayName = "Should serialize & deserialize input sticker with input file id")] @@ -34,40 +38,41 @@ public void Should_Serialize_FileId() { const string fileId = "This-is-a-file_id"; InputFileId inputFileId = new(fileId); - string[] emojiList = new[] { "🙂" }; - InputSticker inputStickerFileId = new InputSticker(inputFileId, emojiList); + string[] emojiList = ["🙂"]; + InputSticker inputStickerFileId = new(inputFileId, emojiList); string json = JsonConvert.SerializeObject(inputStickerFileId); - InputSticker? obj = JsonConvert.DeserializeObject(json); + JObject j = JObject.Parse(json); + + Assert.Equal(2, j.Children().Count()); + Assert.Equal("This-is-a-file_id", j["sticker"]); - InputFileId? objInputFileId = (InputFileId?)obj?.Sticker; + JToken? je = j["emoji_list"]; + Assert.NotNull(je); - Assert.NotNull(obj); - Assert.Equal(emojiList, obj.EmojiList); - Assert.NotNull(objInputFileId); - Assert.Contains(@$"""sticker"":""{fileId}""", json); - Assert.Equal(fileId, objInputFileId.Id); - Assert.Equal(FileType.Id, objInputFileId.FileType); + JArray jEmojiList = Assert.IsType(je); + Assert.Single(jEmojiList); + Assert.Equal("🙂", jEmojiList[0]); } [Fact(DisplayName = "Should serialize & deserialize input sticker with input file URL")] public void Should_Serialize_InputUrlFile() { - Uri url = new("http://github.org/TelegramBots"); + Uri url = new("https://github.com/TelegramBots"); InputFileUrl inputFileUrl = new(url); - string[] emojiList = new[] { "🙂" }; - InputSticker inputStickerFileUrl = new InputSticker(inputFileUrl, emojiList); + string[] emojiList = ["🙂"]; + InputSticker inputStickerFileUrl = new(inputFileUrl, emojiList); string json = JsonConvert.SerializeObject(inputStickerFileUrl); - InputSticker? obj = JsonConvert.DeserializeObject(json); + JObject j = JObject.Parse(json); - InputFileUrl? objInputFileUrl = (InputFileUrl?)obj?.Sticker; + Assert.Equal(2, j.Children().Count()); + Assert.Equal("https://github.com/TelegramBots", j["sticker"]); - Assert.NotNull(obj); - Assert.Equal(emojiList, obj.EmojiList); - Assert.NotNull(objInputFileUrl); - Assert.Contains(@$"""sticker"":""{url}""", json); - Assert.Equal(url, objInputFileUrl.Url); - Assert.Equal(FileType.Url, objInputFileUrl.FileType); + JToken? je = j["emoji_list"]; + Assert.NotNull(je); + JArray jEmojiList = Assert.IsType(je); + Assert.Single(jEmojiList); + Assert.Equal("🙂", jEmojiList[0]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs index 8100e3d29..1ad491cc1 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MenuButtonSerializationTests.cs @@ -1,4 +1,6 @@ +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -10,15 +12,17 @@ public class MenuButtonSerializationTests [Fact] public void Should_Deserialize_Menu_Button_Web_App() { - var button = new + const string button = """ { - type = MenuButtonType.WebApp, - text = "Test text", - web_app = new { url = "https://example.com/link/to/web/app" } - }; + "type": "web_app", + "text": "Test text", + "web_app": { + "url": "https://example.com/link/to/web/app" + } + } + """; - string menuButtonJson = JsonConvert.SerializeObject(button, Formatting.Indented); - MenuButton? menuButton = JsonConvert.DeserializeObject(menuButtonJson); + MenuButton? menuButton = JsonConvert.DeserializeObject(button); MenuButtonWebApp webAppButton = Assert.IsType(menuButton); @@ -40,10 +44,16 @@ public void Should_Serialize_Menu_Button_Web_App() }; string webAppButtonJson = JsonConvert.SerializeObject(webAppButton); - Assert.Contains(@"""type"":""web_app""", webAppButtonJson); - Assert.Contains(@"""text"":""Test text""", webAppButtonJson); - Assert.Contains(@"""web_app"":{", webAppButtonJson); - Assert.Contains(@"""url"":""https://example.com/link/to/web/app""", webAppButtonJson); + JObject j = JObject.Parse(webAppButtonJson); + + Assert.Equal(3, j.Children().Count()); + Assert.Equal("web_app", j["type"]); + Assert.Equal("Test text", j["text"]); + + JToken? jWebApp = j["web_app"]; + Assert.NotNull(jWebApp); + Assert.Single(jWebApp); + Assert.Equal("https://example.com/link/to/web/app", jWebApp["url"]); } [Fact] @@ -65,7 +75,9 @@ public void Should_Serialize_Menu_Button_Default() MenuButtonDefault menuButton = new(); string menuButtonJson = JsonConvert.SerializeObject(menuButton); - Assert.Contains(@"""type"":""default""", menuButtonJson); + JObject j = JObject.Parse(menuButtonJson); + Assert.Single(j); + Assert.Equal("default", j["type"]); } [Fact] @@ -73,12 +85,11 @@ public void Should_Deserialize_Menu_Button_Commands() { var button = new { type = MenuButtonType.Commands, }; - string menuButtonJson = JsonConvert.SerializeObject(button, Formatting.Indented); - MenuButton? menuButton = JsonConvert.DeserializeObject(menuButtonJson); + string menuButtonJson = JsonConvert.SerializeObject(button); + JObject j = JObject.Parse(menuButtonJson); - Assert.NotNull(menuButton); - Assert.Equal(MenuButtonType.Commands, menuButton.Type); - Assert.IsType(menuButton); + Assert.Single(j); + Assert.Equal("commands", j["type"]); } [Fact] @@ -87,6 +98,9 @@ public void Should_Serialize_Menu_Button_Commands() MenuButtonCommands menuButton = new(); string menuButtonJson = JsonConvert.SerializeObject(menuButton); - Assert.Contains(@"""type"":""commands""", menuButtonJson); + JObject j = JObject.Parse(menuButtonJson); + + Assert.Single(j); + Assert.Equal("commands", j["type"]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MessageEntityTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MessageEntityTests.cs index 7fa242f11..7677c32d3 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/MessageEntityTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MessageEntityTests.cs @@ -1,4 +1,6 @@ -using Newtonsoft.Json; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -34,11 +36,13 @@ public void Should_Serialize_Message_Entity_With_Phone_Number_Type() Type = MessageEntityType.PhoneNumber }; - string? json = JsonConvert.SerializeObject(messageEntity); + string json = JsonConvert.SerializeObject(messageEntity); + JObject j = JObject.Parse(json); - Assert.NotNull(json); - Assert.True(json.Length > 10); - Assert.Contains(@"""type"":""phone_number""", json); + Assert.Equal(3, j.Children().Count()); + Assert.Equal(10, j["length"]); + Assert.Equal(10, j["offset"]); + Assert.Equal("phone_number", j["type"]); } [Fact(DisplayName = "Should deserialize message entity with unknown type")] @@ -68,10 +72,12 @@ public void Should_Serialize_Message_Entity_With_Unknown_Type() Type = 0 }; - string? json = JsonConvert.SerializeObject(messageEntity); + string json = JsonConvert.SerializeObject(messageEntity); + JObject j = JObject.Parse(json); - Assert.NotNull(json); - Assert.True(json.Length > 10); - Assert.Contains(@"""type"":""unknown""", json); + Assert.Equal(3, j.Children().Count()); + Assert.Equal(10, j["length"]); + Assert.Equal(10, j["offset"]); + Assert.Equal("unknown", j["type"]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/MethodNameTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/MethodNameTests.cs index 38e29c33e..fa99b2474 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/MethodNameTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/MethodNameTests.cs @@ -1,6 +1,8 @@ +using System.Linq; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Requests; using Xunit; @@ -11,19 +13,29 @@ public class MethodNameTests [Fact(DisplayName = "Should serialize method name in webhook responses")] public void Should_Serialize_MethodName_In_Webhook_Responses() { - SendMessageRequest sendMessageRequest = new(1, "text") { IsWebhookResponse = true }; + SendMessageRequest sendMessageRequest = new(chatId: 1, text: "text") { IsWebhookResponse = true }; string request = JsonConvert.SerializeObject(sendMessageRequest); - Assert.Contains(@"""method"":""sendMessage""", request); + JObject j = JObject.Parse(request); + + Assert.Equal(3, j.Children().Count()); + Assert.Equal(1, j["chat_id"]); + Assert.Equal("text", j["text"]); + Assert.Equal("sendMessage", j["method"]); } [Fact(DisplayName = "Should not serialize method name when not a webhook responses")] public void Should_Not_Serialize_MethodName_When_Not_In_Webhook_Responses() { - SendMessageRequest sendMessageRequest = new(1, "text") { IsWebhookResponse = false }; + SendMessageRequest sendMessageRequest = new(chatId: 1, text: "text") { IsWebhookResponse = false }; string request = JsonConvert.SerializeObject(sendMessageRequest); - Assert.DoesNotContain(@"""method"":""sendMessage""", request); + JObject j = JObject.Parse(request); + + Assert.Equal(2, j.Children().Count()); + Assert.Equal(1, j["chat_id"]); + Assert.Equal("text", j["text"]); + Assert.False(j.ContainsKey("method")); } [Fact(DisplayName = "Should serialize only the method name in parameterless webhook responses")] @@ -32,7 +44,10 @@ public void Should_Serialize_MethodName_In_Parameterless_Webhook_Responses() DeleteWebhookRequest deleteWebhookRequest = new() { IsWebhookResponse = true }; string request = JsonConvert.SerializeObject(deleteWebhookRequest); - Assert.Equal(@"{""method"":""deleteWebhook""}", request); + JObject j = JObject.Parse(request); + + Assert.Single(j.Children()); + Assert.Equal("deleteWebhook", j["method"]); } [Fact(DisplayName = "Should serialize an empty object when not a parameterless webhook response")] @@ -41,7 +56,9 @@ public void Should_Serialize_Empty_Object_When_Not_Parameterless_Webhook_Respons DeleteWebhookRequest deleteWebhookRequest = new() { IsWebhookResponse = false }; string request = JsonConvert.SerializeObject(deleteWebhookRequest); - Assert.Equal("{}", request); + JObject j = JObject.Parse(request); + + Assert.Empty(j.Children()); } [Fact(DisplayName = "Should build a HttpContent in parameterless webhook responses")] @@ -64,7 +81,10 @@ public async Task Should_Build_StringContent_With_MethodName_In_Parameterless_We Assert.NotNull(content); string body = await stringContent.ReadAsStringAsync(); - Assert.Equal(@"{""method"":""close""}", body); + JObject j = JObject.Parse(body); + + Assert.Single(j.Children()); + Assert.Equal("close", j["method"]); } [Fact(DisplayName = "Should not build an HttpContent when not a parameterless webhook responses")] diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/PhotoMessageSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/PhotoMessageSerializationTests.cs index 001a2fade..2e039bc17 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/PhotoMessageSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/PhotoMessageSerializationTests.cs @@ -4,6 +4,7 @@ using Telegram.Bot.Types.Enums; using Xunit; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Telegram.Bot.Tests.Unit.Serialization; @@ -69,10 +70,10 @@ public void Should_Deserialize_PhotoMessage() Assert.NotNull(message); Assert.Equal(MessageType.Photo, message.Type); Assert.NotNull(message.Photo); - Assert.NotEmpty(message.Photo!); + Assert.NotEmpty(message.Photo); Assert.All(message.Photo.Select(ps => ps.FileId), Assert.NotEmpty); - Assert.All(message.Photo.Select(ps => ps.Width), w => Assert.NotEqual(default, w)); - Assert.All(message.Photo.Select(ps => ps.Height), h => Assert.NotEqual(default, h)); + Assert.All(message.Photo.Select(ps => ps.Width), w => Assert.NotEqual(0, w)); + Assert.All(message.Photo.Select(ps => ps.Height), h => Assert.NotEqual(0, h)); } [Fact(DisplayName = "Should serialize a photo message")] @@ -95,9 +96,9 @@ public void Should_Serialize_PhotoMessage() Type = ChatType.Private }, Date = new(2018, 1, 1, 0, 0, 0, DateTimeKind.Utc), - Photo = new[] - { - new PhotoSize + Photo = + [ + new() { FileId = "AgADAgADvKgxGxW80EtRgjrTaWNmy7UerQ4ABN7x5HqnrHW_wp4BAAEC", FileUniqueId = "AgADcOsAAhUdZAc", @@ -105,7 +106,7 @@ public void Should_Serialize_PhotoMessage() Width = 90, Height = 90, }, - new PhotoSize + new() { FileId = "AgADAgADvKgxGxW80EtRgjrTaWNmy7UerQ4ABIrxzSBLXOQYw54BAAEC", FileUniqueId = "AgADcOsAAhUdZAc", @@ -113,7 +114,7 @@ public void Should_Serialize_PhotoMessage() Width = 320, Height = 320, }, - new PhotoSize + new() { FileId = "AgADAgADvKgxGxW80EtRgjrTaWNmy7UerQ4ABIJONRZpTJFnxJ4BAAEC", FileUniqueId = "AgADcOsAAhUdZAc", @@ -121,7 +122,7 @@ public void Should_Serialize_PhotoMessage() Width = 800, Height = 800, }, - new PhotoSize + new() { FileId = "AgADAgADvKgxGxW80EtRgjrTaWNmy7UerQ4ABP6uRLtwe8Z8wZ4BAAEC", FileUniqueId = "AgADcOsAAhUdZAc", @@ -129,13 +130,53 @@ public void Should_Serialize_PhotoMessage() Width = 1280, Height = 1280, } - } + ] }; - string? json = JsonConvert.SerializeObject(message); + string json = JsonConvert.SerializeObject(message); + JObject j = JObject.Parse(json); + + Assert.Equal(5, j.Children().Count()); + Assert.Equal(1234, j["message_id"]); + Assert.Equal(123, j["date"]); + + JToken? jChat = j["chat"]; + Assert.NotNull(jChat); + Assert.Equal(4, jChat.Children().Count()); + Assert.Equal(1234567, jChat["id"]); + Assert.Equal("Telegram_Bots", jChat["first_name"]); + Assert.Equal("TelegramBots", jChat["username"]); + Assert.Equal("private", jChat["type"]); + + JToken? jFrom = j["from"]; + Assert.NotNull(jFrom); + Assert.Equal(4, jFrom.Children().Count()); + Assert.Equal(1234567, jFrom["id"]); + Assert.Equal("Telegram_Bots", jFrom["first_name"]); + Assert.Equal("TelegramBots", jFrom["username"]); + Assert.Equal(false, jFrom["is_bot"]); + + JToken? jPhoto = j["photo"]; + Assert.NotNull(jPhoto); + Assert.IsType(jPhoto); + Assert.Equal(4, jPhoto.Children().Count()); + Assert.All(jPhoto.Children(), photo => + { + Assert.Equal(5, photo.Children().Count()); + Assert.NotNull(photo["file_id"]); + Assert.Equal(JTokenType.String, photo["file_id"]!.Type); + + Assert.NotNull(photo["file_unique_id"]); + Assert.Equal(JTokenType.String, photo["file_unique_id"]!.Type); + + Assert.NotNull(photo["file_size"]); + Assert.Equal(JTokenType.Integer, photo["file_size"]!.Type); + + Assert.NotNull(photo["width"]); + Assert.Equal(JTokenType.Integer, photo["width"]!.Type); - Assert.NotNull(json); - Assert.True(json.Length > 100); - Assert.Contains(@"""file_id"":""AgADAgADvKgxGxW80EtRgjrTaWNmy7UerQ4ABP6uRLtwe8Z8wZ4BAAEC""", json); + Assert.NotNull(photo["height"]); + Assert.Equal(JTokenType.Integer, photo["height"]!.Type); + }); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs index 9d8001129..8096a9d40 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ReplyMarkupSerializationTests.cs @@ -1,4 +1,6 @@ +using System.Linq; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types.ReplyMarkups; using Xunit; @@ -18,12 +20,34 @@ public void Should_Serialize_Request_Poll_Keyboard_Button(string? type) string serializedReplyMarkup = JsonConvert.SerializeObject(replyMarkup); - string formattedType = string.IsNullOrEmpty(type) - ? "{}" - : $@"{{""type"":""{type}""}}"; + JObject j = JObject.Parse(serializedReplyMarkup); + Assert.Single(j); - string expectedString = $@"""request_poll"":{formattedType}"; + JToken? jk = j["keyboard"]; + Assert.NotNull(jk); - Assert.Contains(expectedString, serializedReplyMarkup); + JArray jKeyboard = Assert.IsType(jk); + Assert.Single(jKeyboard); + + JToken jRow = jKeyboard[0]; + Assert.Single(jRow); + + JToken? jButton = jRow[0]; + Assert.NotNull(jButton); + Assert.Equal(2, jButton.Children().Count()); + Assert.Equal("Create a poll", jButton["text"]); + + JToken? jRequestPoll = jButton["request_poll"]; + Assert.NotNull(jRequestPoll); + + if (string.IsNullOrEmpty(type)) + { + Assert.Empty(jRequestPoll); + } + else + { + Assert.Single(jRequestPoll); + Assert.Equal(type, jRequestPoll["type"]); + } } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/RequestSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/RequestSerializationTests.cs index 763ce2e80..892edc622 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/RequestSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/RequestSerializationTests.cs @@ -1,8 +1,10 @@ using System; +using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System.Net.Http; using System.Threading.Tasks; +using Newtonsoft.Json.Linq; using Telegram.Bot.Requests; using Xunit; @@ -17,9 +19,11 @@ public async Task Should_Serialize_DeleteWebhookRequest_Content() HttpContent deleteWebhookContent = deleteWebhookRequest.ToHttpContent()!; string stringContent = await deleteWebhookContent.ReadAsStringAsync(); + JObject j = JObject.Parse(stringContent); - Assert.NotNull(stringContent); - Assert.Contains(@"""drop_pending_updates"":true", stringContent); + + Assert.Single(j); + Assert.Equal(true, j["drop_pending_updates"]); } [Fact(DisplayName = "Should serialize request")] @@ -28,9 +32,10 @@ public void Should_Serialize_Request() GetUpdatesRequest request = new() { Offset = 12345 }; string serializeRequest = JsonConvert.SerializeObject(request); + JObject j = JObject.Parse(serializeRequest); - Assert.DoesNotContain(@"""MethodName""", serializeRequest); - Assert.DoesNotContain(@"""IsWebhookResponse""", serializeRequest); + Assert.Single(j); + Assert.Equal(12345, j["offset"]); } [Fact(DisplayName = "Should properly serialize request with custom json settings")] @@ -51,13 +56,10 @@ public void Should_Properly_Serialize_Request_With_Custom_Json_Settings() }; string serializeRequest = JsonConvert.SerializeObject(request, settings); + JObject j = JObject.Parse(serializeRequest); - Assert.DoesNotContain(@"""MethodName""", serializeRequest); - Assert.DoesNotContain(@"""method_name""", serializeRequest); - Assert.DoesNotContain(@"""IsWebhookResponse""", serializeRequest); - Assert.DoesNotContain(@"""is_webhook_response""", serializeRequest); - Assert.Contains(@"""offset"":12345", serializeRequest); - Assert.DoesNotContain(@"""allowed_updates""", serializeRequest); + Assert.Single(j); + Assert.Equal(12345, j["offset"]); } [Fact(DisplayName = "Should serialize createChatInviteLink request")] @@ -75,11 +77,13 @@ public async Task Should_Serialize_CreateChatInviteLink_Request() HttpContent createChatInviteLinkContent = createChatInviteLinkRequest.ToHttpContent()!; string stringContent = await createChatInviteLinkContent.ReadAsStringAsync(); + JObject j = JObject.Parse(stringContent); - Assert.Contains(@"""expire_date"":1641638025", stringContent); - Assert.Contains(@"""chat_id"":1000000", stringContent); - Assert.Contains(@"""name"":""Test link name""", stringContent); - Assert.Contains(@"""member_limit"":123", stringContent); - Assert.Contains(@"""creates_join_request"":true", stringContent); + Assert.Equal(5, j.Children().Count()); + Assert.Equal(1641638025, j["expire_date"]); + Assert.Equal(1000000, j["chat_id"]); + Assert.Equal("Test link name", j["name"]); + Assert.Equal(123, j["member_limit"]); + Assert.Equal(true, j["creates_join_request"]); } } diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs index 4c8bef8e1..376749add 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/StorySerializationTests.cs @@ -1,4 +1,6 @@ -using Newtonsoft.Json; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Xunit; @@ -21,13 +23,20 @@ public void Should_Serialize_Story() }, }; - Story? deserializedStory = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(story)); + string serializeStory = JsonConvert.SerializeObject(story); - Assert.NotNull(deserializedStory); - Assert.Equal(story.Id, deserializedStory.Id); - Assert.Equal(story.Chat.Id, deserializedStory.Chat.Id); - Assert.Equal(story.Chat.Type, deserializedStory.Chat.Type); - Assert.Equal(story.Chat.Username, deserializedStory.Chat.Username); + JObject j = JObject.Parse(serializeStory); + + Assert.Equal(2, j.Children().Count()); + Assert.Equal(1234, j["id"]); + + JToken? jc = j["chat"]; + Assert.NotNull(jc); + + Assert.Equal(3, jc.Children().Count()); + Assert.Equal(876543, jc["id"]); + Assert.Equal("private", jc["type"]); + Assert.Equal("test_user", jc["username"]); } [Fact] From 70ee6f88eaad40515683363639217ece972dbbd5 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 00:33:31 +0400 Subject: [PATCH 71/90] Use nullable annotation syntax instead of nullability attributes --- src/Telegram.Bot/Types/ApiResponse.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Telegram.Bot/Types/ApiResponse.cs b/src/Telegram.Bot/Types/ApiResponse.cs index 0e2429987..c7d5e89c9 100644 --- a/src/Telegram.Bot/Types/ApiResponse.cs +++ b/src/Telegram.Bot/Types/ApiResponse.cs @@ -1,6 +1,4 @@ -using System.Diagnostics.CodeAnalysis; - -namespace Telegram.Bot.Types; +namespace Telegram.Bot.Types; /// /// Represents bot API response @@ -37,9 +35,7 @@ public class ApiResponse /// Gets the result object. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - [MaybeNull] - [AllowNull] - public TResult Result { get; private set; } + public TResult? Result { get; private set; } /// /// Initializes an instance of From 91f3a7ccf1141a9d37cf88c6d37212919a321509 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 02:21:29 +0400 Subject: [PATCH 72/90] Remove version suffix --- .azure-pipelines/variables.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/variables.yml b/.azure-pipelines/variables.yml index f62e9d522..1631b5aae 100644 --- a/.azure-pipelines/variables.yml +++ b/.azure-pipelines/variables.yml @@ -3,7 +3,7 @@ variables: - name: versionPrefix value: 20.0.0 - name: versionSuffix - value: 'alpha.2' + value: '' - name: ciVersionSuffix value: ci.$(Build.BuildId)+git.commit.$(Build.SourceVersion) - name: isPreRelease From 945cf781225c0f648328f2dd6a7ffba7417a7cee Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 05:49:11 +0400 Subject: [PATCH 73/90] Add required properties from C# 11 --- .../AnswerCallbackQueryRequest.cs | 13 +- .../Commands/SetMyCommandsRequest.cs | 14 +- .../Get Files/GetFileRequest.cs | 16 +- .../Get Files/GetUserProfilePhotosRequest.cs | 14 +- .../GetMyDefaultAdministratorRightsRequest.cs | 3 + .../GetUserChatBoostsRequest.cs | 17 +- .../Manage Chat/BanChatMemberRequest.cs | 16 +- .../Manage Chat/BanChatSenderChatRequest.cs | 16 +- .../ApproveChatJoinRequest.cs | 16 +- .../CreateChatInviteLinkRequest.cs | 14 +- .../DeclineChatJoinRequest.cs | 16 +- .../EditChatInviteLinkRequest.cs | 16 +- .../ExportChatInviteLinkRequest.cs | 14 +- .../RevokeChatInviteLinkRequest.cs | 16 +- .../Manage Chat/CloseForumTopicRequest.cs | 16 +- .../CloseGeneralForumTopicRequest.cs | 16 +- .../Manage Chat/CreateForumTopicRequest.cs | 16 +- .../Manage Chat/DeleteChatPhotoRequest.cs | 14 +- .../DeleteChatStickerSetRequest.cs | 14 +- .../Manage Chat/DeleteForumTopicRequest.cs | 16 +- .../Manage Chat/EditForumTopicRequest.cs | 18 +- .../EditGeneralForumTopicRequest.cs | 18 +- .../Get Chat/GetChatAdministratorsRequest.cs | 14 +- .../Get Chat/GetChatMemberCountRequest.cs | 14 +- .../Get Chat/GetChatMemberRequest.cs | 16 +- .../Manage Chat/Get Chat/GetChatRequest.cs | 14 +- .../HideGeneralForumTopicRequest.cs | 16 +- .../Manage Chat/LeaveChatRequest.cs | 14 +- .../Manage Chat/PinChatMessageRequest.cs | 16 +- .../Manage Chat/PromoteChatMemberRequest.cs | 16 +- .../Manage Chat/ReopenForumTopicRequest.cs | 16 +- .../ReopenGeneralForumTopicRequest.cs | 16 +- .../Manage Chat/RestrictChatMemberRequest.cs | 18 +- .../SetChatAdministratorCustomTitleRequest.cs | 18 +- .../Manage Chat/SetChatDescriptionRequest.cs | 14 +- .../Manage Chat/SetChatPermissionsRequest.cs | 16 +- .../Manage Chat/SetChatPhotoRequest.cs | 16 +- .../Manage Chat/SetChatStickerSetRequest.cs | 16 +- .../Manage Chat/SetChatTitleRequest.cs | 16 +- .../Manage Chat/UnbanChatMemberRequest.cs | 16 +- .../Manage Chat/UnbanChatSenderChatRequest.cs | 16 +- .../UnhideGeneralForumTopicRequest.cs | 15 +- .../UnpinAllChatMessagesRequest.cs | 14 +- .../UnpinAllForumTopicMessagesRequest.cs | 16 +- .../UnpinAllGeneralForumTopicMessages.cs | 14 +- .../Manage Chat/UnpinChatMessageRequest.cs | 14 +- .../Messages/CopyMessageRequest.cs | 18 +- .../Messages/CopyMessagesRequest.cs | 33 +- .../Messages/ForwardMessageRequest.cs | 30 +- .../Messages/ForwardMessagesRequest.cs | 34 +- .../EditInlineMessageLiveLocationRequest.cs | 18 +- .../EditMessageLiveLocationRequest.cs | 20 +- .../Messages/Location/SendLocationRequest.cs | 18 +- .../Messages/Location/SendVenueRequest.cs | 21 +- .../StopInlineMessageLiveLocationRequest.cs | 14 +- .../StopMessageLiveLocationRequest.cs | 16 +- .../Messages/SendAnimationRequest.cs | 28 +- .../Messages/SendAudioRequest.cs | 28 +- .../Messages/SendChatActionRequest.cs | 28 +- .../Messages/SendContactRequest.cs | 30 +- .../Messages/SendDiceRequest.cs | 14 +- .../Messages/SendDocumentRequest.cs | 28 +- .../Messages/SendMediaGroupRequest.cs | 16 +- .../Messages/SendMessageRequest.cs | 26 +- .../Messages/SendPhotoRequest.cs | 18 +- .../Messages/SendPollRequest.cs | 18 +- .../Messages/SendVideoNoteRequest.cs | 16 +- .../Messages/SendVideoRequest.cs | 16 +- .../Messages/SendVoiceRequest.cs | 16 +- .../Messages/SetMessageReactionRequest.cs | 16 +- .../Games/GetGameHighScoresRequest.cs | 20 +- .../Games/GetInlineGameHighScoresRequest.cs | 18 +- .../Requests/Games/SendGameRequest.cs | 16 +- .../Requests/Games/SetGameScoreRequest.cs | 22 +- .../Games/SetInlineGameScoreRequest.cs | 20 +- .../Getting Updates/SetWebhookRequest.cs | 16 +- .../Inline Mode/AnswerInlineQueryRequest.cs | 16 +- .../Inline Mode/AnswerWebAppQueryRequest.cs | 18 +- .../Payments/AnswerPreCheckoutQueryRequest.cs | 21 +- .../Payments/AnswerShippingQueryRequest.cs | 20 +- .../Payments/CreateInvoiceLinkRequest.cs | 25 +- .../Requests/Payments/SendInvoiceRequest.cs | 26 +- .../Stickers/AddStickerToSetRequest.cs | 18 +- .../Stickers/CreateNewStickerSetRequest.cs | 22 +- .../Stickers/DeleteStickerFromSetRequest.cs | 16 +- .../Stickers/DeleteStickerSetRequest.cs | 15 +- .../Stickers/GetCustomEmojiStickersRequest.cs | 19 +- .../Requests/Stickers/GetStickerSetRequest.cs | 16 +- .../Requests/Stickers/SendStickerRequest.cs | 16 +- ...etCustomEmojiStickerSetThumbnailRequest.cs | 15 +- .../Stickers/SetStickerEmojiListRequest.cs | 16 +- .../Stickers/SetStickerKeywordsRequest.cs | 14 +- .../Stickers/SetStickerMaskPositionRequest.cs | 15 +- .../SetStickerPositionInSetRequest.cs | 18 +- .../Stickers/SetStickerSetThumbnailRequest.cs | 16 +- .../Stickers/SetStickerSetTitleRequest.cs | 17 +- .../Stickers/UploadStickerFileRequest.cs | 18 +- .../Updating messages/DeleteMessageRequest.cs | 16 +- .../DeleteMessagesRequest.cs | 16 +- .../EditInlineMessageCaptionRequest.cs | 14 +- .../EditInlineMessageMediaRequest.cs | 16 +- .../EditInlineMessageReplyMarkupRequest.cs | 14 +- .../EditInlineMessageTextRequest.cs | 16 +- .../EditMessageCaptionRequest.cs | 16 +- .../EditMessageMediaRequest.cs | 18 +- .../EditMessageReplyMarkupRequest.cs | 16 +- .../EditMessageTextRequest.cs | 18 +- .../Updating messages/StopPollRequest.cs | 16 +- src/Telegram.Bot/Telegram.Bot.csproj | 2 + src/Telegram.Bot/TelegramBotClient.cs | 2 +- .../TelegramBotClientExtensions.ApiMethods.cs | 662 ++++++++++++------ src/Telegram.Bot/Types/Color.cs | 2 +- .../InlineQueryResult/InlineQueryResult.cs | 11 +- .../InlineQueryResultArticle.cs | 14 +- .../InlineQueryResultAudio.cs | 13 +- .../InlineQueryResultCachedAudio.cs | 11 +- .../InlineQueryResultCachedDocument.cs | 13 +- .../InlineQueryResultCachedGif.cs | 11 +- .../InlineQueryResultCachedMpeg4Gif.cs | 11 +- .../InlineQueryResultCachedPhoto.cs | 11 +- .../InlineQueryResultCachedSticker.cs | 12 +- .../InlineQueryResultCachedVideo.cs | 13 +- .../InlineQueryResultCachedVoice.cs | 13 +- .../InlineQueryResultContact.cs | 14 +- .../InlineQueryResultDocument.cs | 15 +- .../InlineQueryResultGame.cs | 12 +- .../InlineQueryResult/InlineQueryResultGif.cs | 13 +- .../InlineQueryResultLocation.cs | 16 +- .../InlineQueryResultMpeg4Gif.cs | 13 +- .../InlineQueryResultPhoto.cs | 13 +- .../InlineQueryResultVenue.cs | 18 +- .../InlineQueryResultVideo.cs | 17 +- .../InlineQueryResultVoice.cs | 13 +- .../InlineQueryResultsButton.cs | 8 +- .../InputContactMessageContent.cs | 14 +- .../InputInvoiceMessageContent.cs | 21 +- .../InputLocationMessageContent.cs | 14 +- .../InputMessageContent.cs | 2 - .../InputTextMessageContent.cs | 11 +- .../InputVenueMessageContent.cs | 18 +- .../Types/InputFiles/InputFileId.cs | 13 +- .../Types/InputFiles/InputFileStream.cs | 11 +- .../Types/InputFiles/InputFileUrl.cs | 17 +- .../Types/InputFiles/InputMedia/InputMedia.cs | 11 +- .../InputMedia/InputMediaAnimation.cs | 9 + .../InputFiles/InputMedia/InputMediaAudio.cs | 9 + .../InputMedia/InputMediaDocument.cs | 9 + .../InputFiles/InputMedia/InputMediaPhoto.cs | 9 + .../InputFiles/InputMedia/InputMediaVideo.cs | 9 + src/Telegram.Bot/Types/InputSticker.cs | 12 +- .../Types/Payments/LabeledPrice.cs | 13 +- .../Types/ReplyMarkups/IKeyboardButton.cs | 7 +- .../ReplyMarkups/InlineKeyboardButton.cs | 24 +- .../ReplyMarkups/InlineKeyboardMarkup.cs | 5 +- .../Types/ReplyMarkups/KeyboardButton.cs | 5 +- .../ReplyMarkups/KeyboardButtonPollType.cs | 6 +- .../ReplyMarkups/KeyboardButtonRequestChat.cs | 19 +- .../KeyboardButtonRequestUsers.cs | 14 +- .../Types/ReplyMarkups/ReplyKeyboardMarkup.cs | 31 +- .../Types/ReplyMarkups/ReplyKeyboardRemove.cs | 9 +- src/Telegram.Bot/Types/WebAppInfo.cs | 15 +- .../Framework/RetryTelegramBotClient.cs | 47 +- .../Games/GamesTests.cs | 11 +- .../Inline Mode/InlineQueryTests.cs | 296 ++++---- .../InlineMessageLiveLocationTests .cs | 20 +- .../Payments/PaymentsBuilder.cs | 16 +- .../Sending Messages/AlbumMessageTests.cs | 44 +- .../Stickers/StickersTests.cs | 56 +- .../Update Messages/DeleteMessageTests.cs | 13 +- .../EditMessageContentTests.cs | 37 +- .../Update Messages/EditMessageMediaTests.cs | 26 +- .../Update Messages/EditMessageMediaTests2.cs | 6 +- 172 files changed, 2735 insertions(+), 1012 deletions(-) diff --git a/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs b/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs index ea52aee09..55fb0d100 100644 --- a/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -19,7 +21,7 @@ public class AnswerCallbackQueryRequest : RequestBase /// Unique identifier for the query to be answered /// [JsonProperty(Required = Required.Always)] - public string CallbackQueryId { get; } + public required string CallbackQueryId { get; init; } /// /// Text of the notification. If not specified, nothing will be shown to the user, 0-200 characters @@ -54,12 +56,19 @@ public class AnswerCallbackQueryRequest : RequestBase [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public int? CacheTime { get; set; } + /// + /// Initializes a new request with callbackQueryId + /// + public AnswerCallbackQueryRequest() : base("answerCallbackQuery") { } + /// /// Initializes a new request with callbackQueryId /// /// Unique identifier for the query to be answered + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public AnswerCallbackQueryRequest(string callbackQueryId) - : base("answerCallbackQuery") + : this() { CallbackQueryId = callbackQueryId; } diff --git a/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs index 49afa7909..0fe3d091c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -16,7 +17,7 @@ public class SetMyCommandsRequest : RequestBase /// At most 100 commands can be specified. /// [JsonProperty(Required = Required.Always)] - public IEnumerable Commands { get; } + public required IEnumerable Commands { get; init; } /// /// An object, describing scope of users for which the commands are relevant. @@ -36,9 +37,18 @@ public class SetMyCommandsRequest : RequestBase /// Initializes a new request with commands /// /// A list of bot commands to be set + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetMyCommandsRequest(IEnumerable commands) - : base("setMyCommands") + : this() { Commands = commands; } + + /// + /// Initializes a new request with commands + /// + public SetMyCommandsRequest() + : base("setMyCommands") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs b/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs index 6c189f65e..b9675c39b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -21,15 +24,24 @@ public class GetFileRequest : RequestBase /// File identifier to get info about /// [JsonProperty(Required = Required.Always)] - public string FileId { get; } + public required string FileId { get; init; } /// /// Initializes a new request with /// /// File identifier to get info about + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetFileRequest(string fileId) - : base("getFile") + : this() { FileId = fileId; } + + /// + /// Initializes a new request + /// + public GetFileRequest() + : base("getFile") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs b/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs index 1c5efc2e6..e3446c2bc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -12,7 +13,7 @@ public class GetUserProfilePhotosRequest : RequestBase, IUser { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Sequential number of the first photo to be returned. By default, all photos are returned @@ -30,9 +31,18 @@ public class GetUserProfilePhotosRequest : RequestBase, IUser /// Initializes a new request with userId /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetUserProfilePhotosRequest(long userId) - : base("getUserProfilePhotos") + : this() { UserId = userId; } + + /// + /// Initializes a new request with userId + /// + public GetUserProfilePhotosRequest() + : base("getUserProfilePhotos") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/GetMyDefaultAdministratorRightsRequest.cs b/src/Telegram.Bot/Requests/Available methods/GetMyDefaultAdministratorRightsRequest.cs index fde9f8d90..85d99e7c3 100644 --- a/src/Telegram.Bot/Requests/Available methods/GetMyDefaultAdministratorRightsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/GetMyDefaultAdministratorRightsRequest.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// diff --git a/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs index d257fe5f6..5eb9aba40 100644 --- a/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -13,13 +15,20 @@ public class GetUserChatBoostsRequest : RequestBase /// Unique identifier for the chat or username of the channel (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier of the target user /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } + + /// + /// Initializes a new request + /// + public GetUserChatBoostsRequest() + : base("getUserChatBoosts") + { } /// /// Initializes a new request with chatId and userId @@ -28,8 +37,10 @@ public class GetUserChatBoostsRequest : RequestBase /// Unique identifier for the chat or username of the channel (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetUserChatBoostsRequest(ChatId chatId, long userId) - : base("getUserChatBoosts") + : this() { ChatId = chatId; UserId = userId; diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs index e8d3a84f8..ce865fe8c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; @@ -16,11 +17,11 @@ public class BanChatMemberRequest : RequestBase, IChatTargetable, IUserTar { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Date when the user will be unbanned. If user is banned for more than 366 days or less @@ -46,10 +47,19 @@ public class BanChatMemberRequest : RequestBase, IChatTargetable, IUserTar /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public BanChatMemberRequest(ChatId chatId, long userId) - : base("banChatMember") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request + /// + public BanChatMemberRequest() + : base("banChatMember") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs index 2f11e85fa..d959060dc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; @@ -15,13 +16,13 @@ public class BanChatSenderChatRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier of the target sender chat /// [JsonProperty(Required = Required.Always)] - public long SenderChatId { get; } + public required long SenderChatId { get; init; } /// /// Date when the sender chat will be unbanned, unix time. If the chat is banned for more than 366 days or @@ -40,10 +41,19 @@ public class BanChatSenderChatRequest : RequestBase, IChatTargetable /// /// Unique identifier of the target sender chat /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public BanChatSenderChatRequest(ChatId chatId, long senderChatId) - : base("banChatSenderChat") + : this() { ChatId = chatId; SenderChatId = senderChatId; } + + /// + /// Initializes a new request + /// + public BanChatSenderChatRequest() + : base("banChatSenderChat") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs index f27f1ae6f..7213b3fc6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class ApproveChatJoinRequest : RequestBase, IChatTargetable, IUserT { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier of the target user /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Initializes a new request with chatId and userId @@ -28,10 +29,19 @@ public class ApproveChatJoinRequest : RequestBase, IChatTargetable, IUserT /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public ApproveChatJoinRequest(ChatId chatId, long userId) - : base("approveChatJoinRequest") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request with chatId and userId + /// + public ApproveChatJoinRequest() + : base("approveChatJoinRequest") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs index 39364bb9f..3d543b1fb 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; @@ -15,7 +16,7 @@ public class CreateChatInviteLinkRequest : RequestBase, IChatTar { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Invite link name; 0-32 characters @@ -50,9 +51,18 @@ public class CreateChatInviteLinkRequest : RequestBase, IChatTar /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CreateChatInviteLinkRequest(ChatId chatId) - : base("createChatInviteLink") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public CreateChatInviteLinkRequest() + : base("createChatInviteLink") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs index fd62dabf5..f7636cb70 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class DeclineChatJoinRequest : RequestBase, IChatTargetable, IUserT { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier of the target user /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Initializes a new request with chatId and userId @@ -28,10 +29,19 @@ public class DeclineChatJoinRequest : RequestBase, IChatTargetable, IUserT /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeclineChatJoinRequest(ChatId chatId, long userId) - : base("declineChatJoinRequest") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request with chatId and userId + /// + public DeclineChatJoinRequest() + : base("declineChatJoinRequest") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs index 3099e3e01..c5a48f6f0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; @@ -14,13 +15,13 @@ public class EditChatInviteLinkRequest : RequestBase, IChatTarge { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// The invite link to edit /// [JsonProperty(Required = Required.Always)] - public string InviteLink { get; } + public required string InviteLink { get; init; } /// /// Invite link name; 0-32 characters @@ -56,10 +57,19 @@ public class EditChatInviteLinkRequest : RequestBase, IChatTarge /// (in the format @channelusername) /// /// The invite link to edit + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditChatInviteLinkRequest(ChatId chatId, string inviteLink) - : base("editChatInviteLink") + : this() { ChatId = chatId; InviteLink = inviteLink; } + + /// + /// Initializes a new request + /// + public EditChatInviteLinkRequest() + : base("editChatInviteLink") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs index 4254342b6..96fda6433 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,7 +14,7 @@ public class ExportChatInviteLinkRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -21,9 +22,18 @@ public class ExportChatInviteLinkRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public ExportChatInviteLinkRequest(ChatId chatId) - : base("exportChatInviteLink") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request with chatId + /// + public ExportChatInviteLinkRequest() + : base("exportChatInviteLink") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs index 945db9dec..12a4b0e28 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,13 +15,13 @@ public class RevokeChatInviteLinkRequest : RequestBase, IChatTar { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// The invite link to revoke /// [JsonProperty(Required = Required.Always)] - public string InviteLink { get; } + public required string InviteLink { get; init; } /// /// Initializes a new request with chatId and inviteLink @@ -29,10 +30,19 @@ public class RevokeChatInviteLinkRequest : RequestBase, IChatTar /// (in the format @channelusername) /// /// The invite link to revoke + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public RevokeChatInviteLinkRequest(ChatId chatId, string inviteLink) - : base("revokeChatInviteLink") + : this() { ChatId = chatId; InviteLink = inviteLink; } + + /// + /// Initializes a new request with chatId and inviteLink + /// + public RevokeChatInviteLinkRequest() + : base("revokeChatInviteLink") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs index cca6ffebe..1f8de0d8a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,23 +14,32 @@ public class CloseForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread of the forum topic /// [JsonProperty(Required = Required.Always)] - public int MessageThreadId { get; } + public required int MessageThreadId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CloseForumTopicRequest(ChatId chatId, int messageThreadId) - : base("closeForumTopic") + : this() { ChatId = chatId; MessageThreadId = messageThreadId; } + + /// + /// Initializes a new request + /// + public CloseForumTopicRequest() + : base("closeForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs index 2f7998df9..142c4927f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,12 +14,21 @@ public class CloseGeneralForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup - public CloseGeneralForumTopicRequest(ChatId chatId) - : base("closeGeneralForumTopic") => ChatId = chatId; + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] + public CloseGeneralForumTopicRequest(ChatId chatId) : this() + => ChatId = chatId; + + /// + /// Initializes a new request + /// + public CloseGeneralForumTopicRequest() + : base("closeGeneralForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs index c73ddd196..dffe80c32 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Converters; using Telegram.Bot.Requests.Abstractions; @@ -14,13 +15,13 @@ public class CreateForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Topic name, 1-128 characters /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Optional. Color of the topic icon in RGB format. Currently, must be one of 0x6FB9F0, 0xFFD67E, 0xCB86DB, @@ -41,10 +42,19 @@ public class CreateForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup /// Topic name + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CreateForumTopicRequest(ChatId chatId, string name) - : base("createForumTopic") + : this() { ChatId = chatId; Name = name; } + + /// + /// Initializes a new request + /// + public CreateForumTopicRequest() + : base("createForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs index 4881e90de..d5b553ea0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,7 +14,7 @@ public class DeleteChatPhotoRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -21,9 +22,18 @@ public class DeleteChatPhotoRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteChatPhotoRequest(ChatId chatId) - : base("deleteChatPhoto") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public DeleteChatPhotoRequest() + : base("deleteChatPhoto") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs index de3cca835..7ec87c121 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,7 +15,7 @@ public class DeleteChatStickerSetRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -22,9 +23,18 @@ public class DeleteChatStickerSetRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteChatStickerSetRequest(ChatId chatId) - : base("deleteChatStickerSet") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public DeleteChatStickerSetRequest() + : base("deleteChatStickerSet") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs index 644b7cec6..7f03e57d9 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,23 +14,32 @@ public class DeleteForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread of the forum topic /// [JsonProperty(Required = Required.Always)] - public int MessageThreadId { get; } + public required int MessageThreadId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteForumTopicRequest(ChatId chatId, int messageThreadId) - : base("deleteForumTopic") + : this() { ChatId = chatId; MessageThreadId = messageThreadId; } + + /// + /// Initializes a new request + /// + public DeleteForumTopicRequest() + : base("deleteForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs index a267bc979..405f95b34 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class EditForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread of the forum topic /// [JsonProperty(Required = Required.Always)] - public int MessageThreadId { get; } + public required int MessageThreadId { get; init; } /// /// New topic name, 0-128 characters. If not specififed or empty, the current name of the topic will be kept @@ -40,7 +41,16 @@ public class EditForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditForumTopicRequest(ChatId chatId, int messageThreadId) - : base("editForumTopic") => - (ChatId, MessageThreadId) = (chatId, messageThreadId); + : this() + => (ChatId, MessageThreadId) = (chatId, messageThreadId); + + /// + /// Initializes a new request + /// + public EditForumTopicRequest() + : base("editForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs index eb5a76bfd..67aca45c6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,19 +14,28 @@ public class EditGeneralForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// New topic name, 1-128 characters /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup /// New topic name, 1-128 characters - public EditGeneralForumTopicRequest(ChatId chatId, string name) - : base("editGeneralForumTopic") => (ChatId, Name) = (chatId, name); + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] + public EditGeneralForumTopicRequest(ChatId chatId, string name) : this() + => (ChatId, Name) = (chatId, name); + + /// + /// Initializes a new request + /// + public EditGeneralForumTopicRequest() + : base("editGeneralForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs index 221803d8e..43b55eac5 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,7 +15,7 @@ public class GetChatAdministratorsRequest : RequestBase, IChatTarg { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -23,9 +24,18 @@ public class GetChatAdministratorsRequest : RequestBase, IChatTarg /// Unique identifier for the target chat or username of the target supergroup or channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetChatAdministratorsRequest(ChatId chatId) - : base("getChatAdministrators") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public GetChatAdministratorsRequest() + : base("getChatAdministrators") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs index 61fded3b8..9963e88f3 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -11,7 +12,7 @@ public class GetChatMemberCountRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -20,9 +21,18 @@ public class GetChatMemberCountRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup or channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetChatMemberCountRequest(ChatId chatId) - : base("getChatMemberCount") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request with chatId + /// + public GetChatMemberCountRequest() + : base("getChatMemberCount") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs index 0a6197f94..7984c146b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -12,11 +13,11 @@ public class GetChatMemberRequest : RequestBase, IChatTargetable, IU { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Initializes a new request with chatId and userId @@ -26,10 +27,19 @@ public class GetChatMemberRequest : RequestBase, IChatTargetable, IU /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetChatMemberRequest(ChatId chatId, long userId) - : base("getChatMember") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request with chatId and userId + /// + public GetChatMemberRequest() + : base("getChatMember") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs index fb610defd..ba65e0c8d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Converters; using Telegram.Bot.Requests.Abstractions; @@ -15,7 +16,7 @@ public class GetChatRequest : RequestBase, IChatTargetable /// [JsonProperty(Required = Required.Always)] [JsonConverter(typeof(ChatIdConverter))] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -24,9 +25,18 @@ public class GetChatRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup or channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetChatRequest(ChatId chatId) - : base("getChat") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request with chatId + /// + public GetChatRequest() + : base("getChat") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs index 4149de12b..253288b8b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,12 +14,21 @@ public class HideGeneralForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup - public HideGeneralForumTopicRequest(ChatId chatId) - : base("hideGeneralForumTopic") => ChatId = chatId; + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] + public HideGeneralForumTopicRequest(ChatId chatId) : this() + => ChatId = chatId; + + /// + /// Initializes a new request + /// + public HideGeneralForumTopicRequest() + : base("hideGeneralForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs index 5b947c684..02ac77e5f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -11,7 +12,7 @@ public class LeaveChatRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -20,9 +21,18 @@ public class LeaveChatRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup or channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public LeaveChatRequest(ChatId chatId) - : base("leaveChat") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request with chatId + /// + public LeaveChatRequest() + : base("leaveChat") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs index 73dc8ba13..4ee7a28a9 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -15,13 +16,13 @@ public class PinChatMessageRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of a message to pin /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -34,10 +35,19 @@ public class PinChatMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// Identifier of a message to pin + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public PinChatMessageRequest(ChatId chatId, int messageId) - : base("pinChatMessage") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request with chatId and messageId + /// + public PinChatMessageRequest() + : base("pinChatMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs index d13245ac1..ec045a581 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,11 +14,11 @@ public class PromoteChatMemberRequest : RequestBase, IChatTargetable, IUse { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Pass , if the administrator's presence in the chat is hidden @@ -121,10 +122,19 @@ public class PromoteChatMemberRequest : RequestBase, IChatTargetable, IUse /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public PromoteChatMemberRequest(ChatId chatId, long userId) - : base("promoteChatMember") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request + /// + public PromoteChatMemberRequest() + : base("promoteChatMember") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs index 52d6fe8eb..b1d1959fe 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,23 +14,32 @@ public class ReopenForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread of the forum topic /// [JsonProperty(Required = Required.Always)] - public int MessageThreadId { get; } + public required int MessageThreadId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public ReopenForumTopicRequest(ChatId chatId, int messageThreadId) - : base("reopenForumTopic") + : this() { ChatId = chatId; MessageThreadId = messageThreadId; } + + /// + /// Initializes a new request + /// + public ReopenForumTopicRequest() + : base("reopenForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs index 6094c28cb..2fb8bc11f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,12 +14,21 @@ public class ReopenGeneralForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup - public ReopenGeneralForumTopicRequest(ChatId chatId) - : base("reopenGeneralForumTopic") => ChatId = chatId; + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] + public ReopenGeneralForumTopicRequest(ChatId chatId) : this() + => ChatId = chatId; + + /// + /// Initializes a new request + /// + public ReopenGeneralForumTopicRequest() + : base("reopenGeneralForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs index 5fa83aa97..21cf7f0f0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; @@ -14,17 +15,17 @@ public class RestrictChatMemberRequest : RequestBase, IChatTargetable, IUs { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// New user permissions /// [JsonProperty(Required = Required.Always)] - public ChatPermissions Permissions { get; } + public required ChatPermissions Permissions { get; init; } /// /// Pass if chat permissions are set independently. Otherwise, the @@ -56,11 +57,20 @@ public class RestrictChatMemberRequest : RequestBase, IChatTargetable, IUs /// /// Unique identifier of the target user /// New user permissions + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public RestrictChatMemberRequest(ChatId chatId, long userId, ChatPermissions permissions) - : base("restrictChatMember") + : this() { ChatId = chatId; UserId = userId; Permissions = permissions; } + + /// + /// Initializes a new request + /// + public RestrictChatMemberRequest() + : base("restrictChatMember") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs index 8688da527..0e374ab15 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -12,17 +13,17 @@ public class SetChatAdministratorCustomTitleRequest : RequestBase, IChatTa { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// New custom title for the administrator; 0-16 characters, emoji are not allowed /// [JsonProperty(Required = Required.Always)] - public string CustomTitle { get; } + public required string CustomTitle { get; init; } /// /// Initializes a new request with chatId, userId and customTitle @@ -34,11 +35,20 @@ public class SetChatAdministratorCustomTitleRequest : RequestBase, IChatTa /// /// New custom title for the administrator; 0-16 characters, emoji are not allowed /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatAdministratorCustomTitleRequest(ChatId chatId, long userId, string customTitle) - : base("setChatAdministratorCustomTitle") + : this() { ChatId = chatId; UserId = userId; CustomTitle = customTitle; } + + /// + /// Initializes a new request + /// + public SetChatAdministratorCustomTitleRequest() + : base("setChatAdministratorCustomTitle") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs index aa49b0d2c..cce0e3756 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,7 +14,7 @@ public class SetChatDescriptionRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// New chat Description, 0-255 characters @@ -28,9 +29,18 @@ public class SetChatDescriptionRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatDescriptionRequest(ChatId chatId) - : base("setChatDescription") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public SetChatDescriptionRequest() + : base("setChatDescription") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs index 1644dba4f..3c9fdaebb 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class SetChatPermissionsRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// New default chat permissions /// [JsonProperty(Required = Required.Always)] - public ChatPermissions Permissions { get; } + public required ChatPermissions Permissions { get; init; } /// /// Pass if chat permissions are set independently. Otherwise, the @@ -41,10 +42,19 @@ public class SetChatPermissionsRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// New default chat permissions + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatPermissionsRequest(ChatId chatId, ChatPermissions permissions) - : base("setChatPermissions") + : this() { ChatId = chatId; Permissions = permissions; } + + /// + /// Initializes a new request with chatId and new default permissions + /// + public SetChatPermissionsRequest() + : base("setChatPermissions") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs index 2f2c08632..556416fe6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; @@ -14,13 +15,13 @@ public class SetChatPhotoRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// New chat photo, uploaded using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFileStream Photo { get; } + public required InputFileStream Photo { get; init; } /// /// Initializes a new request with chatId and photo @@ -29,13 +30,22 @@ public class SetChatPhotoRequest : FileRequestBase, IChatTargetable /// (in the format @channelusername) /// /// New chat photo, uploaded using multipart/form-data + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatPhotoRequest(ChatId chatId, InputFileStream photo) - : base("setChatPhoto") + : this() { ChatId = chatId; Photo = photo; } + /// + /// Initializes a new request + /// + public SetChatPhotoRequest() + : base("setChatPhoto") + { } + /// public override HttpContent ToHttpContent() => ToMultipartFormDataContent("photo", Photo); diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs index 4bb49a721..6b90e6faf 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,13 +15,13 @@ public class SetChatStickerSetRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Name of the sticker set to be set as the group sticker set /// [JsonProperty(Required = Required.Always)] - public string StickerSetName { get; } + public required string StickerSetName { get; init; } /// /// Initializes a new request with chatId and new stickerSetName @@ -29,10 +30,19 @@ public class SetChatStickerSetRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// Name of the sticker set to be set as the group sticker set + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatStickerSetRequest(ChatId chatId, string stickerSetName) - : base("setChatStickerSet") + : this() { ChatId = chatId; StickerSetName = stickerSetName; } + + /// + /// Initializes a new request + /// + public SetChatStickerSetRequest() + : base("setChatStickerSet") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs index 70ba0f165..acc8cd4dd 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class SetChatTitleRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// New chat title, 1-255 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Initializes a new request with chatId and title @@ -28,10 +29,19 @@ public class SetChatTitleRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// New chat title, 1-255 characters + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetChatTitleRequest(ChatId chatId, string title) - : base("setChatTitle") + : this() { ChatId = chatId; Title = title; } + + /// + /// Initializes a new request with chatId and title + /// + public SetChatTitleRequest() + : base("setChatTitle") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs index 90e57e117..66f33eb25 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -16,11 +17,11 @@ public class UnbanChatMemberRequest : RequestBase, IChatTargetable, IUserT { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Do nothing if the user is not banned @@ -35,10 +36,19 @@ public class UnbanChatMemberRequest : RequestBase, IChatTargetable, IUserT /// (in the format @channelusername) /// /// Unique identifier of the target user + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnbanChatMemberRequest(ChatId chatId, long userId) - : base("unbanChatMember") + : this() { ChatId = chatId; UserId = userId; } + + /// + /// Initializes a new request + /// + public UnbanChatMemberRequest() + : base("unbanChatMember") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs index b24dada2b..ef8a77891 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,13 +14,13 @@ public class UnbanChatSenderChatRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier of the target sender chat /// [JsonProperty(Required = Required.Always)] - public long SenderChatId { get; } + public required long SenderChatId { get; init; } /// /// Initializes a new request with chatId and senderChatId @@ -30,10 +31,19 @@ public class UnbanChatSenderChatRequest : RequestBase, IChatTargetable /// /// Unique identifier of the target sender chat /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnbanChatSenderChatRequest(ChatId chatId, long senderChatId) - : base("unbanChatSenderChat") + : this() { ChatId = chatId; SenderChatId = senderChatId; } + + /// + /// Initializes a new request + /// + public UnbanChatSenderChatRequest() + : base("unbanChatSenderChat") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs index 6a60c4cba..e7a27c115 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,12 +14,22 @@ public class UnhideGeneralForumTopicRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnhideGeneralForumTopicRequest(ChatId chatId) - : base("unhideGeneralForumTopic") => ChatId = chatId; + : this() + => ChatId = chatId; + + /// + /// Initializes a new request + /// + public UnhideGeneralForumTopicRequest() + : base("unhideGeneralForumTopic") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs index 52874d1f6..ec62c121c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -15,7 +16,7 @@ public class UnpinAllChatMessagesRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request with chatId @@ -23,9 +24,18 @@ public class UnpinAllChatMessagesRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnpinAllChatMessagesRequest(ChatId chatId) - : base("unpinAllChatMessages") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request with chatId + /// + public UnpinAllChatMessagesRequest() + : base("unpinAllChatMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs index 86e38cf8c..38d373594 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,23 +14,32 @@ public class UnpinAllForumTopicMessagesRequest : RequestBase, IChatTargeta { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread of the forum topic /// [JsonProperty(Required = Required.Always)] - public int MessageThreadId { get; } + public required int MessageThreadId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnpinAllForumTopicMessagesRequest(ChatId chatId, int messageThreadId) - : base("unpinAllForumTopicMessages") + : this() { ChatId = chatId; MessageThreadId = messageThreadId; } + + /// + /// Initializes a new request + /// + public UnpinAllForumTopicMessagesRequest() + : base("unpinAllForumTopicMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs index bffb715c5..c78d4c004 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -13,15 +14,24 @@ public class UnpinAllGeneralForumTopicMessages : RequestBase, IChatTargeta { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Initializes a new request /// /// Unique identifier for the target chat or username of the target supergroup + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnpinAllGeneralForumTopicMessages(ChatId chatId) - : base("unpinAllGeneralForumTopicMessages") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public UnpinAllGeneralForumTopicMessages() + : base("unpinAllGeneralForumTopicMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs index 53ad93406..9a1611be3 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -15,7 +16,7 @@ public class UnpinChatMessageRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of a message to unpin. If not specified, the most recent pinned message @@ -30,9 +31,18 @@ public class UnpinChatMessageRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UnpinChatMessageRequest(ChatId chatId) - : base("unpinChatMessage") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public UnpinChatMessageRequest() + : base("unpinChatMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs index c20c98b88..67dfa793b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -21,7 +22,7 @@ public class CopyMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -34,13 +35,13 @@ public class CopyMessageRequest : RequestBase, IChatTargetable /// (or channel username in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId FromChatId { get; } + public required ChatId FromChatId { get; init; } /// /// Message identifier in the chat specified in /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// New caption for media, 0-1024 characters after entities parsing. @@ -86,11 +87,20 @@ public class CopyMessageRequest : RequestBase, IChatTargetable /// /// Message identifier in the chat specified in /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CopyMessageRequest(ChatId chatId, ChatId fromChatId, int messageId) - : base("copyMessage") + : this() { ChatId = chatId; FromChatId = fromChatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public CopyMessageRequest() + : base("copyMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs index 180763fe3..36346ba5b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -20,27 +22,27 @@ public class CopyMessagesRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } - - /// - /// Unique identifier for the chat where the original messages were sent + /// Unique identifier for the chat where the original messages were sent /// (or channel username in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId FromChatId { get; } + public required ChatId FromChatId { get; init; } /// /// Identifiers of 1-100 messages in the chat to copy. /// The identifiers must be specified in a strictly increasing order. /// [JsonProperty(Required = Required.Always)] - public int[] MessageIds { get; } + public required IEnumerable MessageIds { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -70,11 +72,20 @@ public class CopyMessagesRequest : RequestBase, IChatTargetable /// Identifiers of 1-100 messages in the chat to copy. /// The identifiers must be specified in a strictly increasing order. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CopyMessagesRequest(ChatId chatId, ChatId fromChatId, int[] messageIds) - : base("copyMessages") + : this() { ChatId = chatId; FromChatId = fromChatId; MessageIds = messageIds; } + + /// + /// Initializes a new request + /// + public CopyMessagesRequest() + : base("copyMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs index 994b22b41..59fa50401 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,26 +15,26 @@ public class ForwardMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the chat where the original message was sent /// (or channel username in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId FromChatId { get; } + public required ChatId FromChatId { get; init; } /// /// Message identifier in the chat specified in /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -56,11 +57,20 @@ public class ForwardMessageRequest : RequestBase, IChatTargetable /// /// Message identifier in the chat specified in /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public ForwardMessageRequest(ChatId chatId, ChatId fromChatId, int messageId) - : base("forwardMessage") + : this() { ChatId = chatId; FromChatId = fromChatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public ForwardMessageRequest() + : base("forwardMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs index d22dbbb3d..f6a6a7c5c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -18,27 +19,27 @@ public class ForwardMessagesRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } - - /// - /// Unique identifier for the chat where the original messages were sent + /// Unique identifier for the chat where the original messages were sent /// (or channel username in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public ChatId FromChatId { get; } + public required ChatId FromChatId { get; init; } /// /// Identifiers of 1-100 messages in the chat from_chat_id to forward. /// The identifiers must be specified in a strictly increasing order. /// [JsonProperty(Required = Required.Always)] - public IEnumerable MessageIds { get; } + public required IEnumerable MessageIds { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -56,18 +57,27 @@ public class ForwardMessagesRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// - /// Unique identifier for the chat where the original messages were sent + /// Unique identifier for the chat where the original messages were sent /// (or channel username in the format @channelusername) /// /// /// Identifiers of 1-100 messages in the chat from_chat_id to forward. /// The identifiers must be specified in a strictly increasing order. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public ForwardMessagesRequest(ChatId chatId, ChatId fromChatId, IEnumerable messageIds) - :base("forwardMessages") + : this() { ChatId = chatId; FromChatId = fromChatId; MessageIds = messageIds; } + + /// + /// Initializes a new request + /// + public ForwardMessagesRequest() + :base("forwardMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs index fa8d1247c..862c83db6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.ReplyMarkups; // ReSharper disable once CheckNamespace @@ -13,19 +14,19 @@ public class EditInlineMessageLiveLocationRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// Latitude of new location /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of new location /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// The radius of uncertainty for the location, measured in meters; 0-1500 @@ -56,11 +57,20 @@ public class EditInlineMessageLiveLocationRequest : RequestBase /// Identifier of the inline message /// Latitude of new location /// Longitude of new location + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditInlineMessageLiveLocationRequest(string inlineMessageId, double latitude, double longitude) - : base("editMessageLiveLocation") + : this() { InlineMessageId = inlineMessageId; Latitude = latitude; Longitude = longitude; } + + /// + /// Initializes a new request + /// + public EditInlineMessageLiveLocationRequest() + : base("editMessageLiveLocation") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs index 239653d94..ace9fe06c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -14,25 +15,25 @@ public class EditMessageLiveLocationRequest : RequestBase, IChatTargeta { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to edit /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// Latitude of new location /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of new location /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// The radius of uncertainty for the location, measured in meters; 0-1500 @@ -67,12 +68,21 @@ public class EditMessageLiveLocationRequest : RequestBase, IChatTargeta /// Identifier of the message to edit /// Latitude of new location /// Longitude of new location + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditMessageLiveLocationRequest(ChatId chatId, int messageId, double latitude, double longitude) - : base("editMessageLiveLocation") + : this() { ChatId = chatId; MessageId = messageId; Latitude = latitude; Longitude = longitude; } + + /// + /// Initializes a new request + /// + public EditMessageLiveLocationRequest() + : base("editMessageLiveLocation") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs index a8deb3ac6..638ac2300 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -12,7 +13,7 @@ public class SendLocationRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -24,13 +25,13 @@ public class SendLocationRequest : RequestBase, IChatTargetable /// Latitude of the location /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of the location /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// The radius of uncertainty for the location, measured in meters; 0-1500 @@ -84,11 +85,20 @@ public class SendLocationRequest : RequestBase, IChatTargetable /// /// Latitude of the location /// Longitude of the location + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendLocationRequest(ChatId chatId, double latitude, double longitude) - : base("sendLocation") + : this() { ChatId = chatId; Latitude = latitude; Longitude = longitude; } + + /// + /// Initializes a new request + /// + public SendLocationRequest() + : base("sendLocation") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs index 5fa5a5923..30df065a4 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -12,7 +13,7 @@ public class SendVenueRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -24,25 +25,25 @@ public class SendVenueRequest : RequestBase, IChatTargetable /// Latitude of the venue /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of the venue /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// Name of the venue /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Address of the venue /// [JsonProperty(Required = Required.Always)] - public string Address { get; } + public required string Address { get; init; } /// /// Foursquare identifier of the venue @@ -96,12 +97,14 @@ public class SendVenueRequest : RequestBase, IChatTargetable /// Longitude of the venue /// Name of the venue /// Address of the venue + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendVenueRequest( ChatId chatId, double latitude, double longitude, string title, - string address) : base("sendVenue") + string address) : this() { ChatId = chatId; Latitude = latitude; @@ -109,4 +112,10 @@ public SendVenueRequest( Title = title; Address = address; } + + /// + /// Initializes a new request + /// + public SendVenueRequest() : base("sendVenue") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs index cd15c54b9..8262b6a8c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.ReplyMarkups; // ReSharper disable once CheckNamespace @@ -12,7 +13,7 @@ public class StopInlineMessageLiveLocationRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -22,9 +23,18 @@ public class StopInlineMessageLiveLocationRequest : RequestBase /// Initializes a new request with inlineMessageId /// /// Identifier of the inline message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public StopInlineMessageLiveLocationRequest(string inlineMessageId) - : base("stopMessageLiveLocation") + : this() { InlineMessageId = inlineMessageId; } + + /// + /// Initializes a new request + /// + public StopInlineMessageLiveLocationRequest() + : base("stopMessageLiveLocation") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs index 2e7420b36..85055bc45 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -14,13 +15,13 @@ public class StopMessageLiveLocationRequest : RequestBase, IChatTargeta { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the sent message /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -33,10 +34,19 @@ public class StopMessageLiveLocationRequest : RequestBase, IChatTargeta /// (in the format @channelusername) /// /// Identifier of the sent message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public StopMessageLiveLocationRequest(ChatId chatId, int messageId) - : base("stopMessageLiveLocation") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public StopMessageLiveLocationRequest() + : base("stopMessageLiveLocation") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs index 4a3ed2e83..71f4182cd 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -18,13 +19,7 @@ public class SendAnimationRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// Animation to send. Pass a as String to send an animation @@ -32,7 +27,13 @@ public class SendAnimationRequest : FileRequestBase, IChatTargetable /// to get an animation from the Internet, or upload a new animation using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFile Animation { get; } + public required InputFile Animation { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// /// Duration of sent animation in seconds @@ -104,13 +105,22 @@ public class SendAnimationRequest : FileRequestBase, IChatTargetable /// that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to /// get an animation from the Internet, or upload a new animation using multipart/form-data /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendAnimationRequest(ChatId chatId, InputFile animation) - : base("sendAnimation") + : this() { ChatId = chatId; Animation = animation; } + /// + /// Initializes a new request + /// + public SendAnimationRequest() + : base("sendAnimation") + { } + /// public override HttpContent? ToHttpContent() => Animation is InputFileStream || Thumbnail is InputFileStream diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs index fae5e36a1..99845b107 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -19,13 +20,7 @@ public class SendAudioRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// Audio file to send. Pass a as String to send an audio @@ -33,7 +28,13 @@ public class SendAudioRequest : FileRequestBase, IChatTargetable /// Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFile Audio { get; } + public required InputFile Audio { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// /// Audio caption, 0-1024 characters after entities parsing @@ -98,13 +99,22 @@ public class SendAudioRequest : FileRequestBase, IChatTargetable /// file that exists on the Telegram servers (recommended), pass an HTTP URL as a String for /// Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendAudioRequest(ChatId chatId, InputFile audio) - : base("sendAudio") + : this() { ChatId = chatId; Audio = audio; } + /// + /// Initializes a new request + /// + public SendAudioRequest() + : base("sendAudio") + { } + /// public override HttpContent? ToHttpContent() => Audio is InputFileStream || Thumbnail is InputFileStream diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs index 9f10e73c2..603f16cc6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; @@ -25,13 +26,7 @@ public class SendChatActionRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread; supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// Type of action to broadcast. Choose one, depending on what the user is about to receive: @@ -46,7 +41,13 @@ public class SendChatActionRequest : RequestBase, IChatTargetable /// video notes /// [JsonProperty(Required = Required.Always)] - public ChatAction Action { get; } + public required ChatAction Action { get; init; } + + /// + /// Unique identifier for the target message thread; supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// /// Initializes a new request chatId and action @@ -57,10 +58,19 @@ public class SendChatActionRequest : RequestBase, IChatTargetable /// /// Type of action to broadcast. Choose one, depending on what the user is about to receive /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendChatActionRequest(ChatId chatId, ChatAction action) - : base("sendChatAction") + : this() { ChatId = chatId; Action = action; } + + /// + /// Initializes a new request + /// + public SendChatActionRequest() + : base("sendChatAction") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs index 4aebb182f..1ac981e38 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -12,25 +13,25 @@ public class SendContactRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// Contact's phone number /// [JsonProperty(Required = Required.Always)] - public string PhoneNumber { get; } + public required string PhoneNumber { get; init; } /// /// Contact's first name /// [JsonProperty(Required = Required.Always)] - public string FirstName { get; } + public required string FirstName { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// /// Contact's last name @@ -68,11 +69,20 @@ public class SendContactRequest : RequestBase, IChatTargetable /// /// Contact's phone number /// Contact's first name + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendContactRequest(ChatId chatId, string phoneNumber, string firstName) - : base("sendContact") + : this() { ChatId = chatId; PhoneNumber = phoneNumber; FirstName = firstName; } + + /// + /// Initializes a new request + /// + public SendContactRequest() + : base("sendContact") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs index fbb817592..5f41eb5b7 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -16,7 +17,7 @@ public class SendDiceRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -51,9 +52,18 @@ public class SendDiceRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendDiceRequest(ChatId chatId) - : base("sendDice") + : this() { ChatId = chatId; } + + /// + /// Initializes a new request + /// + public SendDiceRequest() + : base("sendDice") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs index 556223ebc..3a7d9a36c 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -18,13 +19,7 @@ public class SendDocumentRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } - - /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only - /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + public required ChatId ChatId { get; init; } /// /// File to send. Pass a as String to send a file that @@ -32,7 +27,13 @@ public class SendDocumentRequest : FileRequestBase, IChatTargetable /// to get a file from the Internet, or upload a new one using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFile Document { get; } + public required InputFile Document { get; init; } + + /// + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -86,13 +87,22 @@ public class SendDocumentRequest : FileRequestBase, IChatTargetable /// exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram /// to get a file from the Internet, or upload a new one using multipart/form-data /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendDocumentRequest(ChatId chatId, InputFile document) - : base("sendDocument") + : this() { ChatId = chatId; Document = document; } + /// + /// Initializes a new request + /// + public SendDocumentRequest() + : base("sendDocument") + { } + /// public override HttpContent? ToHttpContent() => Document is InputFileStream || Thumbnail is InputFileStream diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs index f5769330d..59bf897a9 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -16,7 +17,7 @@ public class SendMediaGroupRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -28,7 +29,7 @@ public class SendMediaGroupRequest : FileRequestBase, IChatTargetable /// An array describing messages to be sent, must include 2-10 items /// [JsonProperty(Required = Required.Always)] - public IEnumerable Media { get; } + public required IEnumerable Media { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -50,13 +51,22 @@ public class SendMediaGroupRequest : FileRequestBase, IChatTargetable /// (in the format @channelusername) /// /// An array describing messages to be sent, must include 2-10 items + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendMediaGroupRequest(ChatId chatId, IEnumerable media) - : base("sendMediaGroup") + : this() { ChatId = chatId; Media = media; } + /// + /// Initializes a request + /// + public SendMediaGroupRequest() + : base("sendMediaGroup") + { } + /// public override HttpContent ToHttpContent() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs index cc2c15c49..b080ed5e2 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -14,19 +15,19 @@ public class SendMessageRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// - /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only + /// Text of the message to be sent, 1-4096 characters after entities parsing /// - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public int? MessageThreadId { get; set; } + [JsonProperty(Required = Required.Always)] + public required string Text { get; init; } /// - /// Text of the message to be sent, 1-4096 characters after entities parsing + /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only /// - [JsonProperty(Required = Required.Always)] - public string Text { get; } + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] + public int? MessageThreadId { get; set; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -65,10 +66,19 @@ public class SendMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// Text of the message to be sent, 1-4096 characters after entities parsing + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendMessageRequest(ChatId chatId, string text) - : base("sendMessage") + : this() { ChatId = chatId; Text = text; } + + /// + /// Initializes a new request + /// + public SendMessageRequest() + : base("sendMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs index 6052c11c6..ae5b5e628 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; @@ -15,7 +16,7 @@ public class SendPhotoRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -31,7 +32,7 @@ public class SendPhotoRequest : FileRequestBase, IChatTargetable /// Width and height ratio must be at most 20 /// [JsonProperty(Required = Required.Always)] - public InputFile Photo { get; } + public required InputFile Photo { get; init; } /// /// Photo caption (may also be used when resending photos by ), @@ -82,18 +83,27 @@ public class SendPhotoRequest : FileRequestBase, IChatTargetable /// get a photo from the Internet, or upload a new photo using multipart/form-data. The photo /// must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. /// Width and height ratio must be at most 20 + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendPhotoRequest(ChatId chatId, InputFile photo) - : base("sendPhoto") + : this() { ChatId = chatId; Photo = photo; } + /// + /// Initializes a new request + /// + public SendPhotoRequest() + : base("sendPhoto") + { } + /// public override HttpContent? ToHttpContent() => Photo switch { InputFileStream photo => ToMultipartFormDataContent(fileParameterName: "photo", inputFile: photo), - _ => base.ToHttpContent() + _ => base.ToHttpContent() }; } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs index cc837db05..95ce4f7a5 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Newtonsoft.Json.Converters; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; @@ -15,7 +16,7 @@ public class SendPollRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -27,13 +28,13 @@ public class SendPollRequest : RequestBase, IChatTargetable /// Poll question, 1-300 characters /// [JsonProperty(Required = Required.Always)] - public string Question { get; } + public required string Question { get; init; } /// /// A list of answer options, 2-10 strings 1-100 characters each /// [JsonProperty(Required = Required.Always)] - public IEnumerable Options { get; } + public required IEnumerable Options { get; init; } /// /// , if the poll needs to be anonymous, defaults to @@ -127,11 +128,20 @@ public class SendPollRequest : RequestBase, IChatTargetable /// /// Poll question, 1-300 characters /// A list of answer options, 2-10 strings 1-100 characters each + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendPollRequest(ChatId chatId, string question, IEnumerable options) - : base("sendPoll") + : this() { ChatId = chatId; Question = question; Options = options; } + + /// + /// Initializes a new request + /// + public SendPollRequest() + : base("sendPoll") + { } } diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs index f5b249928..35a213eaa 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -16,7 +17,7 @@ public class SendVideoNoteRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -30,7 +31,7 @@ public class SendVideoNoteRequest : FileRequestBase, IChatTargetable /// multipart/form-data. Sending video notes by a URL is currently unsupported /// [JsonProperty(Required = Required.Always)] - public InputFile VideoNote { get; } + public required InputFile VideoNote { get; init; } /// /// Duration of sent video in seconds @@ -75,13 +76,22 @@ public class SendVideoNoteRequest : FileRequestBase, IChatTargetable /// note that exists on the Telegram servers (recommended) or upload a new video using /// multipart/form-data. Sending video notes by a URL is currently unsupported /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendVideoNoteRequest(ChatId chatId, InputFile videoNote) - : base("sendVideoNote") + : this() { ChatId = chatId; VideoNote = videoNote; } + /// + /// Initializes a new request + /// + public SendVideoNoteRequest() + : base("sendVideoNote") + { } + /// public override HttpContent? ToHttpContent() => VideoNote is InputFileStream || Thumbnail is InputFileStream diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs index 10c909954..1e9afc430 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -18,7 +19,7 @@ public class SendVideoRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -32,7 +33,7 @@ public class SendVideoRequest : FileRequestBase, IChatTargetable /// get a video from the Internet, or upload a new video using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFile Video { get; } + public required InputFile Video { get; init; } /// /// Duration of sent video in seconds @@ -110,13 +111,22 @@ public class SendVideoRequest : FileRequestBase, IChatTargetable /// exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram to /// get a video from the Internet, or upload a new video using multipart/form-data /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendVideoRequest(ChatId chatId, InputFile video) - : base("sendVideo") + : this() { ChatId = chatId; Video = video; } + /// + /// Initializes a new request + /// + public SendVideoRequest() + : base("sendVideo") + { } + /// public override HttpContent? ToHttpContent() => Video is InputFileStream || Thumbnail is InputFileStream diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs index da9600e3b..109a1db5a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; @@ -19,7 +20,7 @@ public class SendVoiceRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -33,7 +34,7 @@ public class SendVoiceRequest : FileRequestBase, IChatTargetable /// a file from the Internet, or upload a new one using multipart/form-data /// [JsonProperty(Required = Required.Always)] - public InputFile Voice { get; } + public required InputFile Voice { get; init; } /// /// Voice message caption, 0-1024 characters after entities parsing @@ -82,13 +83,22 @@ public class SendVoiceRequest : FileRequestBase, IChatTargetable /// that exists on the Telegram servers (recommended), pass an HTTP URL as a String for Telegram /// to get a file from the Internet, or upload a new one using multipart/form-data /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendVoiceRequest(ChatId chatId, InputFile voice) - : base("sendVoice") + : this() { ChatId = chatId; Voice = voice; } + /// + /// Initializes a new request + /// + public SendVoiceRequest() + : base("sendVoice") + { } + /// public override HttpContent? ToHttpContent() => Voice switch diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs index 3c01fb424..46293d99f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -16,14 +17,14 @@ public class SetMessageReactionRequest : RequestBase, { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the target message. If the message belongs to a media group, the reaction /// is set to the first non-deleted message in the group instead. /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// New list of reaction types to set on the message. Currently, as non-premium users, bots can @@ -49,10 +50,19 @@ public class SetMessageReactionRequest : RequestBase, /// Identifier of the target message. If the message belongs to a media group, the reaction /// is set to the first non-deleted message in the group instead. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetMessageReactionRequest(ChatId chatId, int messageId) - : base("setMessageReaction") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public SetMessageReactionRequest() + : base("setMessageReaction") + { } } diff --git a/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs b/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs index d197a7907..f354247d4 100644 --- a/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs +++ b/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs @@ -1,4 +1,5 @@ -using Telegram.Bot.Requests.Abstractions; +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -18,13 +19,13 @@ public class GetGameHighScoresRequest : RequestBase, IUserTarge { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Unique identifier for the target chat /// [JsonProperty(Required = Required.Always)] - public long ChatId { get; } + public required long ChatId { get; init; } /// ChatId IChatTargetable.ChatId => ChatId; @@ -33,7 +34,7 @@ public class GetGameHighScoresRequest : RequestBase, IUserTarge /// Identifier of the sent message /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// Initializes a new request with userId, chatId and messageId @@ -41,11 +42,20 @@ public class GetGameHighScoresRequest : RequestBase, IUserTarge /// Target user id /// Unique identifier for the target chat /// Identifier of the sent message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetGameHighScoresRequest(long userId, long chatId, int messageId) - : base("getGameHighScores") + : this() { UserId = userId; ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public GetGameHighScoresRequest() + : base("getGameHighScores") + { } } diff --git a/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs b/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs index 495b6f48e..b01ecb26f 100644 --- a/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs +++ b/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs @@ -1,4 +1,5 @@ -using Telegram.Bot.Requests.Abstractions; +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -18,21 +19,30 @@ public class GetInlineGameHighScoresRequest : RequestBase, IUse { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// Initializes a new request with userId and inlineMessageId /// /// User identifier /// Identifier of the inline message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetInlineGameHighScoresRequest(long userId, string inlineMessageId) - : base("getGameHighScores") + : this() { UserId = userId; InlineMessageId = inlineMessageId; } + + /// + /// Initializes a new request + /// + public GetInlineGameHighScoresRequest() + : base("getGameHighScores") + { } } diff --git a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs index 3e9094569..140a7febe 100644 --- a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -14,7 +15,7 @@ public class SendGameRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat /// [JsonProperty(Required = Required.Always)] - public long ChatId { get; } + public required long ChatId { get; init; } /// ChatId IChatTargetable.ChatId => ChatId; @@ -30,7 +31,7 @@ public class SendGameRequest : RequestBase, IChatTargetable /// via @BotFather /// [JsonProperty(Required = Required.Always)] - public string GameShortName { get; } + public required string GameShortName { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -56,10 +57,19 @@ public class SendGameRequest : RequestBase, IChatTargetable /// Short name of the game, serves as the unique identifier for the game. Set up your games via /// @BotFather /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendGameRequest(long chatId, string gameShortName) - : base("sendGame") + : this() { ChatId = chatId; GameShortName = gameShortName; } + + /// + /// Initializes a new request + /// + public SendGameRequest() + : base("sendGame") + { } } diff --git a/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs b/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs index 7cfd9d297..83eeed2b3 100644 --- a/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs @@ -1,4 +1,5 @@ -using Telegram.Bot.Requests.Abstractions; +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -13,13 +14,13 @@ public class SetGameScoreRequest : RequestBase, IUserTargetable, IChatT { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// New score, must be non-negative /// [JsonProperty(Required = Required.Always)] - public int Score { get; } + public required int Score { get; init; } /// /// Pass , if the high score is allowed to decrease. This can be useful when fixing mistakes @@ -39,7 +40,7 @@ public class SetGameScoreRequest : RequestBase, IUserTargetable, IChatT /// Unique identifier for the target chat /// [JsonProperty(Required = Required.Always)] - public long ChatId { get; } + public required long ChatId { get; init; } /// ChatId IChatTargetable.ChatId => ChatId; @@ -48,7 +49,7 @@ public class SetGameScoreRequest : RequestBase, IUserTargetable, IChatT /// Identifier of the sent message /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// Initializes a new request @@ -57,12 +58,21 @@ public class SetGameScoreRequest : RequestBase, IUserTargetable, IChatT /// New score, must be non-negative /// Unique identifier for the target chat /// Identifier of the sent message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetGameScoreRequest(long userId, int score, long chatId, int messageId) - : base("setGameScore") + : this() { UserId = userId; Score = score; ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public SetGameScoreRequest() + : base("setGameScore") + { } } diff --git a/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs b/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs index 82dd80fab..680908533 100644 --- a/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs @@ -1,4 +1,5 @@ -using Telegram.Bot.Requests.Abstractions; +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -13,13 +14,13 @@ public class SetInlineGameScoreRequest : RequestBase, IUserTargetable { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// New score, must be non-negative /// [JsonProperty(Required = Required.Always)] - public int Score { get; } + public required int Score { get; init; } /// /// Pass , if the high score is allowed to decrease. This can be useful when fixing mistakes @@ -37,7 +38,7 @@ public class SetInlineGameScoreRequest : RequestBase, IUserTargetable /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// Initializes a new request with userId, inlineMessageId and new score @@ -45,11 +46,20 @@ public class SetInlineGameScoreRequest : RequestBase, IUserTargetable /// User identifier /// New score, must be non-negative /// Identifier of the inline message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetInlineGameScoreRequest(long userId, int score, string inlineMessageId) - : base("setGameScore") + : this() { UserId = userId; Score = score; InlineMessageId = inlineMessageId; } + + /// + /// Initializes a new request + /// + public SetInlineGameScoreRequest() + : base("setGameScore") + { } } diff --git a/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs b/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs index 9cab0c1b7..a5bad7293 100644 --- a/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs +++ b/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Types.Enums; @@ -40,7 +41,7 @@ public class SetWebhookRequest : FileRequestBase /// HTTPS URL to send updates to. Use an empty string to remove webhook integration /// [JsonProperty(Required = Required.Always)] - public string Url { get; } + public required string Url { get; init; } /// /// Upload your public key certificate so that the root certificate in use can be checked. See @@ -100,9 +101,16 @@ public class SetWebhookRequest : FileRequestBase /// /// HTTPS url to send updates to. Use an empty string to remove webhook integration /// - public SetWebhookRequest(string url) - : base("setWebhook") => - Url = url; + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] + public SetWebhookRequest(string url) : base("setWebhook") + => Url = url; + + /// + /// Initializes a new request + /// + public SetWebhookRequest() : base("setWebhook") + { } /// public override HttpContent? ToHttpContent() => diff --git a/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs b/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs index 5bc0bcbe4..36372467f 100644 --- a/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.InlineQueryResults; // ReSharper disable once CheckNamespace @@ -17,13 +18,13 @@ public class AnswerInlineQueryRequest : RequestBase /// Unique identifier for the answered query /// [JsonProperty(Required = Required.Always)] - public string InlineQueryId { get; } + public required string InlineQueryId { get; init; } /// /// An array of results for the inline query /// [JsonProperty(Required = Required.Always)] - public IEnumerable Results { get; } + public required IEnumerable Results { get; init; } /// /// The maximum amount of time in seconds that the result of the @@ -58,10 +59,19 @@ public class AnswerInlineQueryRequest : RequestBase /// /// Unique identifier for the answered query /// An array of results for the inline query + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public AnswerInlineQueryRequest(string inlineQueryId, IEnumerable results) - : base("answerInlineQuery") + : this() { InlineQueryId = inlineQueryId; Results = results; } + + /// + /// Initializes a new request + /// + public AnswerInlineQueryRequest() + : base("answerInlineQuery") + { } } diff --git a/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs b/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs index a4b14f194..09f80532d 100644 --- a/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs @@ -1,4 +1,5 @@ -using Telegram.Bot.Types.InlineQueryResults; +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Types.InlineQueryResults; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -15,23 +16,32 @@ public class AnswerWebAppQueryRequest : RequestBase /// Unique identifier for the query to be answered /// [JsonProperty(Required = Required.Always)] - public string WebAppQueryId { get; } + public required string WebAppQueryId { get; init; } /// /// An object describing the message to be sent /// [JsonProperty(Required = Required.Always)] - public InlineQueryResult Result { get; } + public required InlineQueryResult Result { get; init; } /// /// Initializes a new request with and a /// /// Unique identifier for the query to be answered /// An object describing the message to be sent + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public AnswerWebAppQueryRequest(string webAppQueryId, InlineQueryResult result) - : base("answerWebAppQuery") + : this() { WebAppQueryId = webAppQueryId; Result = result; } + + /// + /// Initializes a new request + /// + public AnswerWebAppQueryRequest() + : base("answerWebAppQuery") + { } } diff --git a/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs b/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs index 7f62bbc09..ecebc5471 100644 --- a/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs @@ -1,4 +1,6 @@ -// ReSharper disable once CheckNamespace +using System.Diagnostics.CodeAnalysis; + +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -17,14 +19,14 @@ public class AnswerPreCheckoutQueryRequest : RequestBase /// Unique identifier for the query to be answered /// [JsonProperty(Required = Required.Always)] - public string PreCheckoutQueryId { get; } + public required string PreCheckoutQueryId { get; init; } /// /// Specify if everything is alright (goods are available, etc.) and the /// bot is ready to proceed with the order. Use if there are any problems. /// [JsonProperty(Required = Required.Always)] - public bool Ok { get; } + public required bool Ok { get; init; } /// /// Required if is . Error message in human readable form that explains @@ -39,8 +41,9 @@ public class AnswerPreCheckoutQueryRequest : RequestBase /// Initializes a new successful answerPreCheckoutQuery request /// /// Unique identifier for the query to be answered + [SetsRequiredMembers] public AnswerPreCheckoutQueryRequest(string preCheckoutQueryId) - : base("answerPreCheckoutQuery") + : this() { PreCheckoutQueryId = preCheckoutQueryId; Ok = true; @@ -56,11 +59,19 @@ public AnswerPreCheckoutQueryRequest(string preCheckoutQueryId) /// our amazing black T-shirts while you were busy filling out your payment details. Please /// choose a different color or garment!"). Telegram will display this message to the user. /// + [SetsRequiredMembers] public AnswerPreCheckoutQueryRequest(string preCheckoutQueryId, string errorMessage) - : base("answerPreCheckoutQuery") + : this() { PreCheckoutQueryId = preCheckoutQueryId; Ok = false; ErrorMessage = errorMessage; } + + /// + /// Initializes a new failing answerPreCheckoutQuery request with error message + /// + public AnswerPreCheckoutQueryRequest() + : base("answerPreCheckoutQuery") + { } } diff --git a/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs b/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs index 64d07c70e..f54c9026d 100644 --- a/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Payments; // ReSharper disable once CheckNamespace @@ -17,20 +18,20 @@ public class AnswerShippingQueryRequest : RequestBase /// Unique identifier for the query to be answered /// [JsonProperty(Required = Required.Always)] - public string ShippingQueryId { get; } + public required string ShippingQueryId { get; init; } /// /// Specify if delivery to the specified address is possible and /// if there are any problems (for example, if delivery to the specified address is not possible) /// [JsonProperty(Required = Required.Always)] - public bool Ok { get; } + public required bool Ok { get; init; } /// /// Required if is . An array of available shipping options. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public IEnumerable? ShippingOptions { get; } + public IEnumerable? ShippingOptions { get; init; } /// /// Required if is . Error message in human readable form that explains @@ -45,8 +46,9 @@ public class AnswerShippingQueryRequest : RequestBase /// /// Unique identifier for the query to be answered /// Error message in human readable form + [SetsRequiredMembers] public AnswerShippingQueryRequest(string shippingQueryId, string errorMessage) - : base("answerShippingQuery") + : this() { ShippingQueryId = shippingQueryId; Ok = false; @@ -58,12 +60,20 @@ public AnswerShippingQueryRequest(string shippingQueryId, string errorMessage) /// /// Unique identifier for the query to be answered /// A JSON-serialized array of available shipping options + [SetsRequiredMembers] public AnswerShippingQueryRequest( string shippingQueryId, - IEnumerable shippingOptions) : base("answerShippingQuery") + IEnumerable shippingOptions) : this() { ShippingQueryId = shippingQueryId; Ok = true; ShippingOptions = shippingOptions; } + + /// + /// Initializes a new request + /// + public AnswerShippingQueryRequest() + : base("answerShippingQuery") + { } } diff --git a/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs b/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs index 7d4c3b715..5d71ed0ae 100644 --- a/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Payments; // ReSharper disable once CheckNamespace @@ -14,40 +15,40 @@ public class CreateInvoiceLinkRequest : RequestBase /// Product name, 1-32 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Product description, 1-255 characters /// [JsonProperty(Required = Required.Always)] - public string Description { get; } + public required string Description { get; init; } /// /// Bot-defined invoice payload, 1-128 bytes.This will not be displayed to the user, /// use for your internal processes. /// [JsonProperty(Required = Required.Always)] - public string Payload { get; } + public required string Payload { get; init; } /// /// Payments provider token, obtained via @BotFather /// [JsonProperty(Required = Required.Always)] - public string ProviderToken { get; } + public required string ProviderToken { get; init; } /// /// Three-letter ISO 4217 currency code, see /// more on currencies /// [JsonProperty(Required = Required.Always)] - public string Currency { get; } + public required string Currency { get; init; } /// /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// [JsonProperty(Required = Required.Always)] - public IEnumerable Prices { get; } + public required IEnumerable Prices { get; init; } /// /// The maximum accepted amount for tips in the smallest units of the currency. @@ -160,13 +161,16 @@ public class CreateInvoiceLinkRequest : RequestBase /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CreateInvoiceLinkRequest( string title, string description, string payload, string providerToken, string currency, - IEnumerable prices) : base("createInvoiceLink") + IEnumerable prices) + : this() { Title = title; Description = description; @@ -175,4 +179,11 @@ public CreateInvoiceLinkRequest( Currency = currency; Prices = prices; } + + /// + /// Initializes a new request + /// + public CreateInvoiceLinkRequest() + : base("createInvoiceLink") + { } } diff --git a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs index 9ae0e304d..e0d6c1cc5 100644 --- a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Payments; using Telegram.Bot.Types.ReplyMarkups; @@ -17,7 +18,7 @@ public class SendInvoiceRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [JsonProperty(Required = Required.Always)] - public long ChatId { get; } + public required long ChatId { get; init; } /// ChatId IChatTargetable.ChatId => ChatId; @@ -32,40 +33,40 @@ public class SendInvoiceRequest : RequestBase, IChatTargetable /// Product name, 1-32 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Product description, 1-255 characters /// [JsonProperty(Required = Required.Always)] - public string Description { get; } + public required string Description { get; init; } /// /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, /// use for your internal processes /// [JsonProperty(Required = Required.Always)] - public string Payload { get; } + public required string Payload { get; init; } /// /// Payments provider token, obtained via @BotFather /// [JsonProperty(Required = Required.Always)] - public string ProviderToken { get; } + public required string ProviderToken { get; init; } /// /// Three-letter ISO 4217 currency code, see /// more on currencies /// [JsonProperty(Required = Required.Always)] - public string Currency { get; } + public required string Currency { get; init; } /// /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// [JsonProperty(Required = Required.Always)] - public IEnumerable Prices { get; } + public required IEnumerable Prices { get; init; } /// /// The maximum accepted amount for tips in the smallest units of the currency. @@ -208,6 +209,8 @@ public class SendInvoiceRequest : RequestBase, IChatTargetable /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendInvoiceRequest( long chatId, string title, @@ -215,7 +218,7 @@ public SendInvoiceRequest( string payload, string providerToken, string currency, - IEnumerable prices) : base("sendInvoice") + IEnumerable prices) : this() { ChatId = chatId; Title = title; @@ -225,4 +228,11 @@ public SendInvoiceRequest( Currency = currency; Prices = prices; } + + /// + /// Initializes a new request + /// + public SendInvoiceRequest() + : base("sendInvoice") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs index fe4267fa5..5db8dacec 100644 --- a/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; @@ -25,20 +26,20 @@ public class AddStickerToSetRequest : FileRequestBase, IUserTargetable { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Sticker set name /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// A JSON-serialized object with information about the added sticker. /// If exactly the same sticker had already been added to the set, then the set isn't changed. /// [JsonProperty(Required = Required.Always)] - public InputSticker Sticker { get; } + public required InputSticker Sticker { get; init; } /// /// Initializes a new request with userId, name and sticker @@ -53,17 +54,26 @@ public class AddStickerToSetRequest : FileRequestBase, IUserTargetable /// A JSON-serialized object with information about the added sticker. /// If exactly the same sticker had already been added to the set, then the set isn't changed. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public AddStickerToSetRequest( long userId, string name, InputSticker sticker) - : base("addStickerToSet") + : this() { UserId = userId; Name = name; Sticker = sticker; } + /// + /// Initializes a new request + /// + public AddStickerToSetRequest() + : base("addStickerToSet") + { } + /// public override HttpContent? ToHttpContent() => diff --git a/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs index a4294d61c..f9f4f9fb7 100644 --- a/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -17,7 +18,7 @@ public class CreateNewStickerSetRequest : FileRequestBase, IUserTargetable { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// Short name of sticker set, to be used in t.me/addstickers/ URLs (e.g., animals). @@ -26,25 +27,25 @@ public class CreateNewStickerSetRequest : FileRequestBase, IUserTargetable /// <bot_username> is case insensitive. 1-64 characters /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Sticker set title, 1-64 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// A JSON-serialized list of 1-50 initial stickers to be added to the sticker set /// [JsonProperty(Required = Required.Always)] - public IEnumerable Stickers { get; } + public required IEnumerable Stickers { get; init; } /// /// Format of stickers in the set. /// [JsonProperty(Required = Required.Always)] - public StickerFormat StickerFormat { get; } + public required StickerFormat StickerFormat { get; init; } /// /// Type of stickers in the set. @@ -83,13 +84,15 @@ public class CreateNewStickerSetRequest : FileRequestBase, IUserTargetable /// /// Format of stickers in the set. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public CreateNewStickerSetRequest( long userId, string name, string title, IEnumerable stickers, StickerFormat stickerFormat) - : base("createNewStickerSet") + : this() { UserId = userId; Name = name; @@ -98,6 +101,13 @@ public CreateNewStickerSetRequest( StickerFormat = stickerFormat; } + /// + /// Initializes a new request + /// + public CreateNewStickerSetRequest() + : base("createNewStickerSet") + { } + /// public override HttpContent ToHttpContent() { diff --git a/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs index 5c0956669..0eca11442 100644 --- a/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -11,7 +14,7 @@ public class DeleteStickerFromSetRequest : RequestBase /// File identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public InputFileId Sticker { get; } + public required InputFileId Sticker { get; init; } /// /// Initializes a new request with sticker @@ -19,9 +22,18 @@ public class DeleteStickerFromSetRequest : RequestBase /// /// File identifier of the sticker /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteStickerFromSetRequest(InputFileId sticker) - : base("deleteStickerFromSet") + : this() { Sticker = sticker; } + + /// + /// Initializes a new request with sticker + /// + public DeleteStickerFromSetRequest() + : base("deleteStickerFromSet") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs index 2efd192e7..ba5ebc150 100644 --- a/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -11,7 +13,7 @@ namespace Telegram.Bot.Requests; /// Sticker set name /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Initializes a new request with name @@ -19,9 +21,18 @@ namespace Telegram.Bot.Requests; /// /// Sticker set name /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteStickerSetRequest(string name) - : base("deleteStickerSet") + : this() { Name = name; } + + /// + /// Initializes a new request + /// + public DeleteStickerSetRequest() + : base("deleteStickerSet") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs b/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs index c9a641e25..97a3e87d9 100644 --- a/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; @@ -14,16 +15,26 @@ public class GetCustomEmojiStickersRequest : RequestBase /// List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified. /// [JsonProperty(Required = Required.Always)] - public IEnumerable CustomEmojiIds { get; } + public required IEnumerable CustomEmojiIds { get; init; } /// /// Initializes a new request with name /// - /// List of custom emoji identifiers. At most 200 custom emoji - /// identifiers can be specified. + /// + /// List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified. + /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetCustomEmojiStickersRequest(IEnumerable customEmojiIds) - : base("getCustomEmojiStickers") + : this() { CustomEmojiIds = customEmojiIds; } + + /// + /// Initializes a new request with name + /// + public GetCustomEmojiStickersRequest() + : base("getCustomEmojiStickers") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs index 261a3bca6..c27016e22 100644 --- a/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -11,15 +14,24 @@ public class GetStickerSetRequest : RequestBase /// Name of the sticker set /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Initializes a new request with name /// /// Name of the sticker set + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public GetStickerSetRequest(string name) - : base("getStickerSet") + : this() { Name = name; } + + /// + /// Initializes a new request with name + /// + public GetStickerSetRequest() + : base("getStickerSet") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs index e4b34bf6e..f4948174f 100644 --- a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -14,7 +15,7 @@ public class SendStickerRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Optional. Unique identifier for the target message thread (topic) of the forum; for forum supergroups only @@ -31,7 +32,7 @@ public class SendStickerRequest : FileRequestBase, IChatTargetable /// Animated stickers can't be sent via an HTTP URL. /// [JsonProperty(Required = Required.Always)] - public InputFile Sticker { get; } + public required InputFile Sticker { get; init; } /// /// Optional. Emoji associated with the sticker; only for just uploaded stickers @@ -70,13 +71,22 @@ public class SendStickerRequest : FileRequestBase, IChatTargetable /// Video stickers can only be sent by a . /// Animated stickers can't be sent via an HTTP URL. /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SendStickerRequest(ChatId chatId, InputFile sticker) - : base("sendSticker") + : this() { ChatId = chatId; Sticker = sticker; } + /// + /// Initializes a new request chatId and sticker + /// + public SendStickerRequest() + : base("sendSticker") + { } + /// public override HttpContent? ToHttpContent() => Sticker switch diff --git a/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs index a4f33948c..f525cfb66 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -11,7 +13,7 @@ public class SetCustomEmojiStickerSetThumbnailRequest : RequestBase /// Sticker set name /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Optional. Custom emoji identifier of a from the ; @@ -26,9 +28,18 @@ public class SetCustomEmojiStickerSetThumbnailRequest : RequestBase /// /// Sticker set name /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetCustomEmojiStickerSetThumbnailRequest(string name) - : base("setCustomEmojiStickerSetThumbnail") + : this() { Name = name; } + + /// + /// Initializes a new request + /// + public SetCustomEmojiStickerSetThumbnailRequest() + : base("setCustomEmojiStickerSetThumbnail") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs index 3b88db490..aed873477 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Telegram.Bot.Requests; @@ -14,13 +15,13 @@ public class SetStickerEmojiListRequest : RequestBase /// File identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public InputFileId Sticker { get; } + public required InputFileId Sticker { get; init; } /// /// A JSON-serialized list of 1-20 emoji associated with the sticker /// [JsonProperty(Required = Required.Always)] - public IEnumerable EmojiList { get; } + public required IEnumerable EmojiList { get; init; } /// /// Initializes a new request with sticker and emojiList @@ -31,10 +32,19 @@ public class SetStickerEmojiListRequest : RequestBase /// /// A JSON-serialized list of 1-20 emoji associated with the sticker /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerEmojiListRequest(InputFileId sticker, IEnumerable emojiList) - : base("setStickerEmojiList") + : this() { Sticker = sticker; EmojiList = emojiList; } + + /// + /// Initializes a new request + /// + public SetStickerEmojiListRequest() + : base("setStickerEmojiList") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs index 28b66a993..a9e49a6e3 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Telegram.Bot.Requests; @@ -14,7 +15,7 @@ public class SetStickerKeywordsRequest : RequestBase /// File identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public InputFileId Sticker { get; } + public required InputFileId Sticker { get; init; } /// /// Optional. A JSON-serialized list of 0-20 search keywords for the sticker @@ -29,9 +30,18 @@ public class SetStickerKeywordsRequest : RequestBase /// /// File identifier of the sticker /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerKeywordsRequest(InputFileId sticker) - : base("setStickerKeywords") + : this() { Sticker = sticker; } + + /// + /// Initializes a new request + /// + public SetStickerKeywordsRequest() + : base("setStickerKeywords") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs index 277f35d14..8895e77c9 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -13,7 +15,7 @@ public class SetStickerMaskPositionRequest : RequestBase /// File identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public InputFileId Sticker { get; } + public required InputFileId Sticker { get; init; } /// /// A JSON-serialized object with the position where the mask should be placed on faces. @@ -28,9 +30,18 @@ public class SetStickerMaskPositionRequest : RequestBase /// /// File identifier of the sticker /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerMaskPositionRequest(InputFileId sticker) - : base("setStickerMaskPosition") + : this() { Sticker = sticker; } + + /// + /// Initializes a new request + /// + public SetStickerMaskPositionRequest() + : base("setStickerMaskPosition") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs index 83676b6ec..2e192afe1 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs @@ -1,4 +1,7 @@ // ReSharper disable once CheckNamespace + +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -12,13 +15,13 @@ public class SetStickerPositionInSetRequest : RequestBase /// File identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public InputFileId Sticker { get; } + public required InputFileId Sticker { get; init; } /// /// New sticker position in the set, zero-based /// [JsonProperty(Required = Required.Always)] - public int Position { get; } + public required int Position { get; init; } /// /// Initializes a new request with sticker and position @@ -27,10 +30,19 @@ public class SetStickerPositionInSetRequest : RequestBase /// File identifier of the sticker /// /// New sticker position in the set, zero-based + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerPositionInSetRequest(InputFileId sticker, int position) - : base("setStickerPositionInSet") + : this() { Sticker = sticker; Position = position; } + + /// + /// Initializes a new request + /// + public SetStickerPositionInSetRequest() + : base("setStickerPositionInSet") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs index 34e7d8ad0..c10074193 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; @@ -16,11 +17,11 @@ public class SetStickerSetThumbnailRequest : FileRequestBase, IUserTargeta /// Sticker set name /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// A .WEBP or .PNG image with the thumbnail, must be up to 128 kilobytes in size and have @@ -41,13 +42,22 @@ public class SetStickerSetThumbnailRequest : FileRequestBase, IUserTargeta /// /// Sticker set name /// User identifier of the sticker set owner + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerSetThumbnailRequest(string name, long userId) - : base("setStickerSetThumbnail") + : this() { Name = name; UserId = userId; } + /// + /// Initializes a new request + /// + public SetStickerSetThumbnailRequest() + : base("setStickerSetThumbnail") + { } + /// public override HttpContent? ToHttpContent() => Thumbnail switch diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs index 130546cc1..af9ce734b 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Requests; /// @@ -11,13 +13,13 @@ public class SetStickerSetTitleRequest : RequestBase /// Sticker set name /// [JsonProperty(Required = Required.Always)] - public string Name { get; } + public required string Name { get; init; } /// /// Sticker set title, 1-64 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Initializes a new request with name and title @@ -28,10 +30,19 @@ public class SetStickerSetTitleRequest : RequestBase /// /// Sticker set title, 1-64 characters /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public SetStickerSetTitleRequest(string name, string title) - : base("setStickerSetTitle") + : this() { Name = name; Title = title; } + + /// + /// Initializes a new request + /// + public SetStickerSetTitleRequest() + : base("setStickerSetTitle") + { } } diff --git a/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs b/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs index 8d7250a4c..233dbf0a4 100644 --- a/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; @@ -17,19 +18,19 @@ public class UploadStickerFileRequest : FileRequestBase, IUserTargetable { /// [JsonProperty(Required = Required.Always)] - public long UserId { get; } + public required long UserId { get; init; } /// /// A file with the sticker in .WEBP, .PNG, .TGS, or .WEBM format. /// [JsonProperty(Required = Required.Always)] - public InputFileStream Sticker { get; } + public required InputFileStream Sticker { get; init; } /// /// Format of the sticker /// [JsonProperty(Required = Required.Always)] - public StickerFormat StickerFormat { get; } + public required StickerFormat StickerFormat { get; init; } /// /// Initializes a new request with userId, sticker and stickerFormat @@ -43,14 +44,23 @@ public class UploadStickerFileRequest : FileRequestBase, IUserTargetable /// /// Format of the sticker /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public UploadStickerFileRequest(long userId, InputFileStream sticker, StickerFormat stickerFormat) - : base("uploadStickerFile") + : this() { UserId = userId; Sticker = sticker; StickerFormat = stickerFormat; } + /// + /// Initializes a new request + /// + public UploadStickerFileRequest() + : base("uploadStickerFile") + { } + /// public override HttpContent? ToHttpContent() => ToMultipartFormDataContent(fileParameterName: "sticker", inputFile: Sticker); diff --git a/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs b/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs index a4d3b2c88..eb152327b 100644 --- a/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -24,13 +25,13 @@ public class DeleteMessageRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to delete /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// Initializes a new request with chatId and messageId @@ -40,10 +41,19 @@ public class DeleteMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// Identifier of the message to delete + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteMessageRequest(ChatId chatId, int messageId) - : base("deleteMessage") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public DeleteMessageRequest() + : base("deleteMessage") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs index 44ed5526b..097944b9d 100644 --- a/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; // ReSharper disable once CheckNamespace @@ -14,14 +15,14 @@ public class DeleteMessagesRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifiers of 1-100 messages to delete. See /// for limitations on which messages can be deleted /// [JsonProperty(Required = Required.Always)] - public IEnumerable MessageIds { get; } + public required IEnumerable MessageIds { get; init; } /// /// Initializes a new request with chatId and messageIds @@ -34,10 +35,19 @@ public class DeleteMessagesRequest : RequestBase, IChatTargetable /// Identifiers of 1-100 messages to delete. See /// for limitations on which messages can be deleted /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public DeleteMessagesRequest(ChatId chatId, IEnumerable messageIds) - :base("deleteMessages") + : this() { ChatId = chatId; MessageIds = messageIds; } + + /// + /// Initializes a new request with chatId and messageIds + /// + public DeleteMessagesRequest() + : base("deleteMessages") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs index a2e2899a2..a8ff5a1dc 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -14,7 +15,7 @@ public class EditInlineMessageCaptionRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// New caption of the message, 0-1024 characters after entities parsing @@ -38,9 +39,18 @@ public class EditInlineMessageCaptionRequest : RequestBase /// Initializes a new request with inlineMessageId and new caption /// /// Identifier of the inline message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditInlineMessageCaptionRequest(string inlineMessageId) - : base("editMessageCaption") + : this() { InlineMessageId = inlineMessageId; } + + /// + /// Initializes a new request with inlineMessageId and new caption + /// + public EditInlineMessageCaptionRequest() + : base("editMessageCaption") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs index b54ce9e58..bc88982ec 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -16,13 +17,13 @@ public class EditInlineMessageMediaRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// A new media content of the message /// [JsonProperty(Required = Required.Always)] - public InputMedia Media { get; } + public required InputMedia Media { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -33,10 +34,19 @@ public class EditInlineMessageMediaRequest : RequestBase /// /// Identifier of the inline message /// A new media content of the message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditInlineMessageMediaRequest(string inlineMessageId, InputMedia media) - : base("editMessageMedia") + : this() { InlineMessageId = inlineMessageId; Media = media; } + + /// + /// Initializes a new request with inlineMessageId and new media + /// + public EditInlineMessageMediaRequest() + : base("editMessageMedia") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs index cd8bdd2a2..fdd3147f6 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -12,7 +13,7 @@ public class EditInlineMessageReplyMarkupRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -22,9 +23,18 @@ public class EditInlineMessageReplyMarkupRequest : RequestBase /// Initializes a new request with inlineMessageId and new inline keyboard /// /// Identifier of the inline message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditInlineMessageReplyMarkupRequest(string inlineMessageId) - : base("editMessageReplyMarkup") + : this() { InlineMessageId = inlineMessageId; } + + /// + /// Initializes a new request + /// + public EditInlineMessageReplyMarkupRequest() + : base("editMessageReplyMarkup") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs index 87770203b..42f6d7ea0 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -14,13 +15,13 @@ public class EditInlineMessageTextRequest : RequestBase { /// [JsonProperty(Required = Required.Always)] - public string InlineMessageId { get; } + public required string InlineMessageId { get; init; } /// /// New text of the message, 1-4096 characters after entities parsing /// [JsonProperty(Required = Required.Always)] - public string Text { get; } + public required string Text { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -45,10 +46,19 @@ public class EditInlineMessageTextRequest : RequestBase /// /// Identifier of the inline message /// New text of the message, 1-4096 characters after entities parsing + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditInlineMessageTextRequest(string inlineMessageId, string text) - : base("editMessageText") + : this() { InlineMessageId = inlineMessageId; Text = text; } + + /// + /// Initializes a new request with inlineMessageId and new text + /// + public EditInlineMessageTextRequest() + : base("editMessageText") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs index ba67b17cf..aaf5df188 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -14,13 +15,13 @@ public class EditMessageCaptionRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to edit /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// New caption of the message, 0-1024 characters after entities parsing @@ -47,10 +48,19 @@ public class EditMessageCaptionRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// /// Identifier of the message to edit + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditMessageCaptionRequest(ChatId chatId, int messageId) - : base("editMessageCaption") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request with chatId and messageIdn + /// + public EditMessageCaptionRequest() + : base("editMessageCaption") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs index c7396d401..87794f897 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.Net.Http; using Telegram.Bot.Extensions; using Telegram.Bot.Requests.Abstractions; @@ -19,19 +20,19 @@ public class EditMessageMediaRequest : FileRequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to edit /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// A new media content of the message /// [JsonProperty(Required = Required.Always)] - public InputMedia Media { get; } + public required InputMedia Media { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -46,14 +47,23 @@ public class EditMessageMediaRequest : FileRequestBase, IChatTargetable /// /// Identifier of the message to edit /// A new media content of the message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditMessageMediaRequest(ChatId chatId, int messageId, InputMedia media) - : base("editMessageMedia") + : this() { ChatId = chatId; MessageId = messageId; Media = media; } + /// + /// Initializes a new + /// + public EditMessageMediaRequest() + : base("editMessageMedia") + { } + /// public override HttpContent? ToHttpContent() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs index 7335fbf35..3a8d06956 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -13,13 +14,13 @@ public class EditMessageReplyMarkupRequest : RequestBase, IChatTargetab { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to edit /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -33,10 +34,19 @@ public class EditMessageReplyMarkupRequest : RequestBase, IChatTargetab /// (in the format @channelusername) /// /// Identifier of the message to edit + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditMessageReplyMarkupRequest(ChatId chatId, int messageId) - : base("editMessageReplyMarkup") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request with chatId and messageId + /// + public EditMessageReplyMarkupRequest() + : base("editMessageReplyMarkup") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs index 2670697af..0dd1eaabd 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -14,19 +15,19 @@ public class EditMessageTextRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the message to edit /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// /// New text of the message, 1-4096 characters after entities parsing /// [JsonProperty(Required = Required.Always)] - public string Text { get; } + public required string Text { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -55,11 +56,20 @@ public class EditMessageTextRequest : RequestBase, IChatTargetable /// /// Identifier of the message to edit /// New text of the message, 1-4096 characters after entities parsing + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public EditMessageTextRequest(ChatId chatId, int messageId, string text) - : base("editMessageText") + : this() { ChatId = chatId; MessageId = messageId; Text = text; } + + /// + /// Initializes a new request + /// + public EditMessageTextRequest() + : base("editMessageText") + { } } diff --git a/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs b/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs index 0eadcf287..a26319044 100644 --- a/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Requests.Abstractions; using Telegram.Bot.Types.ReplyMarkups; @@ -14,13 +15,13 @@ public class StopPollRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] - public ChatId ChatId { get; } + public required ChatId ChatId { get; init; } /// /// Identifier of the original message with the poll /// [JsonProperty(Required = Required.Always)] - public int MessageId { get; } + public required int MessageId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -34,10 +35,19 @@ public class StopPollRequest : RequestBase, IChatTargetable /// @channelusername) /// /// Identifier of the original message with the poll + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public StopPollRequest(ChatId chatId, int messageId) - : base("stopPoll") + : this() { ChatId = chatId; MessageId = messageId; } + + /// + /// Initializes a new request + /// + public StopPollRequest() + : base("stopPoll") + { } } diff --git a/src/Telegram.Bot/Telegram.Bot.csproj b/src/Telegram.Bot/Telegram.Bot.csproj index 8fbe478f8..437e94ca9 100644 --- a/src/Telegram.Bot/Telegram.Bot.csproj +++ b/src/Telegram.Bot/Telegram.Bot.csproj @@ -83,6 +83,8 @@ + + diff --git a/src/Telegram.Bot/TelegramBotClient.cs b/src/Telegram.Bot/TelegramBotClient.cs index 39065db50..bdf77b08c 100644 --- a/src/Telegram.Bot/TelegramBotClient.cs +++ b/src/Telegram.Bot/TelegramBotClient.cs @@ -149,7 +149,7 @@ response.Description is null var apiResponse = await httpResponse .DeserializeContentAsync>( - guard: response => response.Ok == false || + guard: response => !response.Ok || response.Result is null ) .ConfigureAwait(false); diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 2fde02262..42376ac3a 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -70,12 +70,12 @@ public static async Task GetUpdatesAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetUpdatesRequest + new GetUpdatesRequest { Offset = offset, Limit = limit, Timeout = timeout, - AllowedUpdates = allowedUpdates + AllowedUpdates = allowedUpdates, }, cancellationToken ) @@ -160,8 +160,9 @@ public static async Task SetWebhookAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetWebhookRequest(url) + new SetWebhookRequest { + Url = url, Certificate = certificate, IpAddress = ipAddress, MaxConnections = maxConnections, @@ -190,10 +191,7 @@ public static async Task DeleteWebhookAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new DeleteWebhookRequest - { - DropPendingUpdates = dropPendingUpdates - }, + new DeleteWebhookRequest { DropPendingUpdates = dropPendingUpdates }, cancellationToken ) .ConfigureAwait(false); @@ -214,7 +212,7 @@ public static async Task GetWebhookInfoAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetWebhookInfoRequest(), cancellationToken) + .MakeRequestAsync(new GetWebhookInfoRequest(), cancellationToken) .ConfigureAwait(false); #endregion Getting updates @@ -234,7 +232,7 @@ public static async Task GetMeAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetMeRequest(), cancellationToken) + .MakeRequestAsync(new GetMeRequest(), cancellationToken) .ConfigureAwait(false); /// @@ -252,7 +250,7 @@ public static async Task LogOutAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new LogOutRequest(), cancellationToken) + .MakeRequestAsync(new LogOutRequest(), cancellationToken) .ConfigureAwait(false); /// @@ -269,7 +267,7 @@ public static async Task CloseAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new CloseRequest(), cancellationToken) + .MakeRequestAsync(new CloseRequest(), cancellationToken) .ConfigureAwait(false); /// @@ -325,8 +323,10 @@ public static async Task SendTextMessageAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendMessageRequest(chatId, text) + new SendMessageRequest { + ChatId = chatId, + Text = text, MessageThreadId = messageThreadId, ParseMode = parseMode, Entities = entities, @@ -376,8 +376,11 @@ public static async Task ForwardMessageAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new ForwardMessageRequest(chatId, fromChatId, messageId) + new ForwardMessageRequest { + ChatId = chatId, + FromChatId = fromChatId, + MessageId = messageId, MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, @@ -397,7 +400,7 @@ await botClient.ThrowIfNull() /// (in the format @channelusername) /// /// - /// Unique identifier for the chat where the original messages were sent + /// Unique identifier for the chat where the original messages were sent /// (or channel username in the format @channelusername) /// /// @@ -429,8 +432,11 @@ public static async Task ForwardMessagesAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new ForwardMessagesRequest(chatId, fromChatId, messageIds) + new ForwardMessagesRequest { + ChatId = chatId, + FromChatId = fromChatId, + MessageIds = messageIds, MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, @@ -502,8 +508,11 @@ public static async Task CopyMessageAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new CopyMessageRequest(chatId, fromChatId, messageId) + new CopyMessageRequest { + ChatId = chatId, + FromChatId = fromChatId, + MessageId = messageId, MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, @@ -531,7 +540,7 @@ await botClient.ThrowIfNull() /// (in the format @channelusername) /// /// - /// Unique identifier for the chat where the original messages were sent + /// Unique identifier for the chat where the original messages were sent /// (or channel username in the format @channelusername) /// /// @@ -547,7 +556,7 @@ await botClient.ThrowIfNull() /// /// Protects the contents of sent messages from forwarding and saving /// - /// + /// /// Pass to copy the messages without their captions /// /// @@ -562,17 +571,20 @@ public static async Task CopyMessagesAsync( int? messageThreadId = default, bool? disableNotification = default, bool? protectContent = default, - bool? RemoveCaption = default, + bool? removeCaption = default, CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new CopyMessagesRequest(chatId, fromChatId, messageIds) + new CopyMessagesRequest { + ChatId = chatId, + FromChatId = fromChatId, + MessageIds = messageIds, MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, - RemoveCaption = RemoveCaption, + RemoveCaption = removeCaption, }, cancellationToken ) @@ -643,8 +655,10 @@ public static async Task SendPhotoAsync( ) => await botClient.ThrowIfNull(). MakeRequestAsync( - request: new SendPhotoRequest(chatId, photo) + new SendPhotoRequest { + ChatId = chatId, + Photo = photo, MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, @@ -732,8 +746,10 @@ public static async Task SendAudioAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendAudioRequest(chatId, audio) + new SendAudioRequest { + ChatId = chatId, + Audio = audio, MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, @@ -824,8 +840,10 @@ public static async Task SendDocumentAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendDocumentRequest(chatId, document) + new SendDocumentRequest { + ChatId = chatId, + Document = document, MessageThreadId = messageThreadId, Thumbnail = thumbnail, Caption = caption, @@ -922,8 +940,10 @@ public static async Task SendVideoAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendVideoRequest(chatId, video) + new SendVideoRequest { + ChatId = chatId, + Video = video, MessageThreadId = messageThreadId, Duration = duration, Width = width, @@ -1022,8 +1042,10 @@ public static async Task SendAnimationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendAnimationRequest(chatId, animation) + new SendAnimationRequest { + ChatId = chatId, + Animation = animation, MessageThreadId = messageThreadId, Duration = duration, Width = width, @@ -1104,8 +1126,10 @@ public static async Task SendVoiceAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendVoiceRequest(chatId, voice) + new SendVoiceRequest { + ChatId = chatId, + Voice = voice, MessageThreadId = messageThreadId, Caption = caption, ParseMode = parseMode, @@ -1177,8 +1201,10 @@ public static async Task SendVideoNoteAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendVideoNoteRequest(chatId, videoNote) + new SendVideoNoteRequest { + ChatId = chatId, + VideoNote = videoNote, MessageThreadId = messageThreadId, Duration = duration, Length = length, @@ -1226,8 +1252,10 @@ public static async Task SendMediaGroupAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendMediaGroupRequest(chatId, media) + new SendMediaGroupRequest { + ChatId = chatId, + Media = media, MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, @@ -1295,8 +1323,11 @@ public static async Task SendLocationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendLocationRequest(chatId, latitude, longitude) + new SendLocationRequest { + ChatId = chatId, + Latitude = latitude, + Longitude = longitude, MessageThreadId = messageThreadId, HorizontalAccuracy = horizontalAccuracy, LivePeriod = livePeriod, @@ -1358,12 +1389,16 @@ public static async Task EditMessageLiveLocationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditMessageLiveLocationRequest(chatId, messageId, latitude, longitude) + new EditMessageLiveLocationRequest { + ChatId = chatId, + MessageId = messageId, + Latitude = latitude, + Longitude = longitude, HorizontalAccuracy = horizontalAccuracy, Heading = heading, ProximityAlertRadius = proximityAlertRadius, - ReplyMarkup = replyMarkup + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -1410,8 +1445,11 @@ public static async Task EditMessageLiveLocationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditInlineMessageLiveLocationRequest(inlineMessageId, latitude, longitude) + new EditInlineMessageLiveLocationRequest { + InlineMessageId = inlineMessageId, + Latitude = latitude, + Longitude = longitude, HorizontalAccuracy = horizontalAccuracy, Heading = heading, ProximityAlertRadius = proximityAlertRadius, @@ -1450,9 +1488,11 @@ public static async Task StopMessageLiveLocationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new StopMessageLiveLocationRequest(chatId, messageId) + new StopMessageLiveLocationRequest { - ReplyMarkup = replyMarkup + ChatId = chatId, + MessageId = messageId, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -1481,9 +1521,10 @@ public static async Task StopMessageLiveLocationAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new StopInlineMessageLiveLocationRequest(inlineMessageId) + new StopInlineMessageLiveLocationRequest { - ReplyMarkup = replyMarkup + InlineMessageId = inlineMessageId, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -1550,8 +1591,13 @@ public static async Task SendVenueAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendVenueRequest(chatId, latitude, longitude, title, address) + new SendVenueRequest { + ChatId = chatId, + Latitude = latitude, + Longitude = longitude, + Title = title, + Address = address, FoursquareId = foursquareId, FoursquareType = foursquareType, GooglePlaceId = googlePlaceId, @@ -1612,8 +1658,11 @@ public static async Task SendContactAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendContactRequest(chatId, phoneNumber, firstName) + new SendContactRequest { + ChatId = chatId, + PhoneNumber = phoneNumber, + FirstName = firstName, LastName = lastName, Vcard = vCard, DisableNotification = disableNotification, @@ -1714,8 +1763,11 @@ public static async Task SendPollAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendPollRequest(chatId, question, options) + new SendPollRequest { + ChatId = chatId, + Question = question, + Options = options, MessageThreadId = messageThreadId, IsAnonymous = isAnonymous, Type = type, @@ -1783,8 +1835,9 @@ public static async Task SendDiceAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendDiceRequest(chatId) + new SendDiceRequest { + ChatId = chatId, MessageThreadId = messageThreadId, Emoji = emoji, DisableNotification = disableNotification, @@ -1842,7 +1895,12 @@ public static async Task SendChatActionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new SendChatActionRequest(chatId, chatAction) { MessageThreadId = messageThreadId }, + new SendChatActionRequest + { + ChatId = chatId, + Action = chatAction, + MessageThreadId = messageThreadId, + }, cancellationToken) .ConfigureAwait(false); @@ -1881,8 +1939,10 @@ public static async Task SetMessageReactionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new SetMessageReactionRequest(chatId, messageId) + new SetMessageReactionRequest { + ChatId = chatId, + MessageId = messageId, Reaction = reaction, IsBig = isBig, }, @@ -1913,10 +1973,11 @@ public static async Task GetUserProfilePhotosAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetUserProfilePhotosRequest(userId) + new GetUserProfilePhotosRequest { + UserId = userId, Offset = offset, - Limit = limit + Limit = limit, }, cancellationToken ) @@ -1946,8 +2007,8 @@ public static async Task GetFileAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetFileRequest(fileId), - cancellationToken: cancellationToken + new GetFileRequest { FileId = fileId }, + cancellationToken ) .ConfigureAwait(false); @@ -1969,7 +2030,7 @@ public static async Task GetInfoAndDownloadFileAsync( CancellationToken cancellationToken = default) { var file = await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetFileRequest(fileId), cancellationToken) + .MakeRequestAsync(new GetFileRequest { FileId = fileId }, cancellationToken) .ConfigureAwait(false); await botClient.DownloadFileAsync(filePath: file.FilePath!, destination, cancellationToken) @@ -2013,10 +2074,12 @@ public static async Task BanChatMemberAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new BanChatMemberRequest(chatId, userId) + new BanChatMemberRequest { + ChatId = chatId, + UserId = userId, UntilDate = untilDate, - RevokeMessages = revokeMessages + RevokeMessages = revokeMessages, }, cancellationToken ) @@ -2048,9 +2111,11 @@ public static async Task UnbanChatMemberAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new UnbanChatMemberRequest(chatId, userId) + new UnbanChatMemberRequest { - OnlyIfBanned = onlyIfBanned + ChatId = chatId, + UserId = userId, + OnlyIfBanned = onlyIfBanned, }, cancellationToken ) @@ -2093,8 +2158,11 @@ public static async Task RestrictChatMemberAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new RestrictChatMemberRequest(chatId, userId, permissions) + new RestrictChatMemberRequest { + ChatId = chatId, + UserId = userId, + Permissions = permissions, UntilDate = untilDate, UseIndependentChatPermissions = useIndependentChatPermissions, }, @@ -2103,7 +2171,9 @@ await botClient.ThrowIfNull() .ConfigureAwait(false); /// - /// Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in the chat for this to work and must have the appropriate admin rights. Pass for all boolean parameters to demote a user. + /// Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in + /// the chat for this to work and must have the appropriate admin rights. Pass for + /// all boolean parameters to demote a user. /// /// An instance of /// @@ -2111,21 +2181,56 @@ await botClient.ThrowIfNull() /// (in the format @channelusername) /// /// Unique identifier of the target user - /// Pass , if the administrator's presence in the chat is hidden - /// Pass , if the administrator can access the chat event log, chat statistics, message statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. Implied by any other administrator privilege - /// Pass , if the administrator can create channel posts, channels only - /// Pass , if the administrator can edit messages of other users, channels only - /// Pass , if the administrator can delete messages of other users - /// Pass if the administrator can post stories in the channel; channels only - /// Pass if the administrator can edit stories posted by other users; channels only - /// Pass if the administrator can delete stories posted by other users; channels only - /// Pass , if the administrator can manage voice chats, supergroups only - /// Pass , if the administrator can restrict, ban or unban chat members - /// Pass , if the administrator can add new administrators with a subset of his own privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators that were appointed by him) - /// Pass , if the administrator can change chat title, photo and other settings - /// Pass , if the administrator can invite new users to the chat - /// Pass , if the administrator can pin messages, supergroups only - /// Pass if the user is allowed to create, rename, close, and reopen forum topics, supergroups only + /// + /// Pass , if the administrator's presence in the chat is hidden + /// + /// + /// Pass , if the administrator can access the chat event log, chat statistics, message + /// statistics in channels, see channel members, see anonymous administrators in supergroups and ignore slow mode. + /// Implied by any other administrator privilege + /// + /// + /// Pass , if the administrator can create channel posts, channels only + /// + /// + /// Pass , if the administrator can edit messages of other users, channels only + /// + /// + /// Pass , if the administrator can delete messages of other users + /// + /// + /// Pass if the administrator can post stories in the channel; channels only + /// + /// + /// Pass if the administrator can edit stories posted by other users; channels only + /// + /// + /// Pass if the administrator can delete stories posted by other users; channels only + /// + /// + /// Pass , if the administrator can manage voice chats, supergroups only + /// + /// + /// Pass , if the administrator can restrict, ban or unban chat members + /// + /// + /// Pass , if the administrator can add new administrators with a subset of his own + /// privileges or demote administrators that he has promoted, directly or indirectly (promoted by administrators + /// that were appointed by him) + /// + /// + /// Pass , if the administrator can change chat title, photo and other settings + /// + /// + /// Pass , if the administrator can invite new users to the chat + /// + /// + /// Pass , if the administrator can pin messages, supergroups only + /// + /// + /// Pass if the user is allowed to create, rename, close, and reopen forum topics, + /// supergroups only + /// /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// @@ -2152,8 +2257,10 @@ public static async Task PromoteChatMemberAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new PromoteChatMemberRequest(chatId, userId) + new PromoteChatMemberRequest { + ChatId = chatId, + UserId = userId, IsAnonymous = isAnonymous, CanManageChat = canManageChat, CanPostMessages = canPostMessages, @@ -2198,7 +2305,12 @@ public static async Task SetChatAdministratorCustomTitleAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetChatAdministratorCustomTitleRequest(chatId, userId, customTitle), + new SetChatAdministratorCustomTitleRequest + { + ChatId = chatId, + UserId = userId, + CustomTitle = customTitle, + }, cancellationToken ) .ConfigureAwait(false); @@ -2225,7 +2337,11 @@ public static async Task BanChatSenderChatAsync(this ITelegramBotClient botClien ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new BanChatSenderChatRequest(chatId, senderChatId), + new BanChatSenderChatRequest + { + ChatId = chatId, + SenderChatId = senderChatId, + }, cancellationToken ) .ConfigureAwait(false); @@ -2251,7 +2367,11 @@ public static async Task UnbanChatSenderChatAsync(this ITelegramBotClient botCli ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new UnbanChatSenderChatRequest(chatId, senderChatId), + new UnbanChatSenderChatRequest + { + ChatId = chatId, + SenderChatId = senderChatId, + }, cancellationToken ) .ConfigureAwait(false); @@ -2288,8 +2408,10 @@ public static async Task SetChatPermissionsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetChatPermissionsRequest(chatId, permissions) + new SetChatPermissionsRequest { + ChatId = chatId, + Permissions = permissions, UseIndependentChatPermissions = useIndependentChatPermissions, }, cancellationToken @@ -2316,7 +2438,10 @@ public static async Task ExportChatInviteLinkAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new ExportChatInviteLinkRequest(chatId), + new ExportChatInviteLinkRequest + { + ChatId = chatId, + }, cancellationToken ) .ConfigureAwait(false); @@ -2356,8 +2481,9 @@ public static async Task CreateChatInviteLinkAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new CreateChatInviteLinkRequest(chatId) + new CreateChatInviteLinkRequest { + ChatId = chatId, Name = name, ExpireDate = expireDate, MemberLimit = memberLimit, @@ -2403,8 +2529,10 @@ public static async Task EditChatInviteLinkAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditChatInviteLinkRequest(chatId, inviteLink) + new EditChatInviteLinkRequest { + ChatId = chatId, + InviteLink = inviteLink, Name = name, ExpireDate = expireDate, MemberLimit = memberLimit, @@ -2437,7 +2565,11 @@ public static async Task RevokeChatInviteLinkAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new RevokeChatInviteLinkRequest(chatId, inviteLink), + new RevokeChatInviteLinkRequest + { + ChatId = chatId, + InviteLink = inviteLink, + }, cancellationToken ) .ConfigureAwait(false); @@ -2464,7 +2596,11 @@ public static async Task ApproveChatJoinRequest( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new ApproveChatJoinRequest(chatId, userId), + new ApproveChatJoinRequest + { + ChatId = chatId, + UserId = userId, + }, cancellationToken ) .ConfigureAwait(false); @@ -2491,7 +2627,11 @@ public static async Task DeclineChatJoinRequest( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new DeclineChatJoinRequest(chatId, userId), + new DeclineChatJoinRequest + { + ChatId = chatId, + UserId = userId, + }, cancellationToken ) .ConfigureAwait(false); @@ -2517,7 +2657,11 @@ public static async Task SetChatPhotoAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetChatPhotoRequest(chatId, photo), + new SetChatPhotoRequest + { + ChatId = chatId, + Photo = photo, + }, cancellationToken) .ConfigureAwait(false); @@ -2539,7 +2683,7 @@ public static async Task DeleteChatPhotoAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new DeleteChatPhotoRequest(chatId), + new DeleteChatPhotoRequest { ChatId = chatId }, cancellationToken ) .ConfigureAwait(false); @@ -2564,7 +2708,14 @@ public static async Task SetChatTitleAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new SetChatTitleRequest(chatId, title), cancellationToken) + .MakeRequestAsync( + new SetChatTitleRequest + { + ChatId = chatId, + Title = title, + }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -2588,7 +2739,7 @@ public static async Task SetChatDescriptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetChatDescriptionRequest(chatId) { Description = description }, + new SetChatDescriptionRequest { ChatId = chatId, Description = description }, cancellationToken ) .ConfigureAwait(false); @@ -2621,9 +2772,11 @@ public static async Task PinChatMessageAsync( ) => await botClient.ThrowIfNull(). MakeRequestAsync( - request: new PinChatMessageRequest(chatId, messageId) + new PinChatMessageRequest { - DisableNotification = disableNotification + ChatId = chatId, + MessageId = messageId, + DisableNotification = disableNotification, }, cancellationToken ) @@ -2655,7 +2808,7 @@ public static async Task UnpinChatMessageAsync( ) => await botClient.ThrowIfNull(). MakeRequestAsync( - request: new UnpinChatMessageRequest(chatId) { MessageId = messageId }, + new UnpinChatMessageRequest { ChatId = chatId, MessageId = messageId }, cancellationToken ) .ConfigureAwait(false); @@ -2680,7 +2833,7 @@ public static async Task UnpinAllChatMessages( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull(). - MakeRequestAsync(request: new UnpinAllChatMessagesRequest(chatId), cancellationToken) + MakeRequestAsync(new UnpinAllChatMessagesRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2700,7 +2853,7 @@ public static async Task LeaveChatAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull(). - MakeRequestAsync(request: new LeaveChatRequest(chatId), cancellationToken) + MakeRequestAsync(new LeaveChatRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2722,7 +2875,7 @@ public static async Task GetChatAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetChatRequest(chatId), cancellationToken) + .MakeRequestAsync(new GetChatRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2747,7 +2900,7 @@ public static async Task GetChatAdministratorsAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetChatAdministratorsRequest(chatId), cancellationToken) + .MakeRequestAsync(new GetChatAdministratorsRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2768,7 +2921,7 @@ public static async Task GetChatMemberCountAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetChatMemberCountRequest(chatId), cancellationToken) + .MakeRequestAsync(new GetChatMemberCountRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2791,7 +2944,10 @@ public static async Task GetChatMemberAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetChatMemberRequest(chatId, userId), cancellationToken) + .MakeRequestAsync( + new GetChatMemberRequest { ChatId = chatId, UserId = userId }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -2816,7 +2972,10 @@ public static async Task SetChatStickerSetAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new SetChatStickerSetRequest(chatId, stickerSetName), cancellationToken) + .MakeRequestAsync( + new SetChatStickerSetRequest { ChatId = chatId, StickerSetName = stickerSetName }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -2839,7 +2998,7 @@ public static async Task DeleteChatStickerSetAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new DeleteChatStickerSetRequest(chatId), cancellationToken) + .MakeRequestAsync(new DeleteChatStickerSetRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -2893,8 +3052,10 @@ public static async Task CreateForumTopicAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new CreateForumTopicRequest(chatId, name) + new CreateForumTopicRequest { + ChatId = chatId, + Name = name, IconColor = iconColor, IconCustomEmojiId = iconCustomEmojiId, }, @@ -2934,8 +3095,10 @@ public static async Task EditForumTopicAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - new EditForumTopicRequest(chatId, messageThreadId) + new EditForumTopicRequest { + ChatId = chatId, + MessageThreadId = messageThreadId, Name = name, IconCustomEmojiId = iconCustomEmojiId, }, @@ -2964,7 +3127,10 @@ public static async Task CloseForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new CloseForumTopicRequest(chatId, messageThreadId), cancellationToken) + .MakeRequestAsync( + new CloseForumTopicRequest { ChatId = chatId, MessageThreadId = messageThreadId }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -2988,7 +3154,10 @@ public static async Task ReopenForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new ReopenForumTopicRequest(chatId, messageThreadId), cancellationToken) + .MakeRequestAsync( + new ReopenForumTopicRequest { ChatId = chatId, MessageThreadId = messageThreadId }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -3013,7 +3182,10 @@ public static async Task DeleteForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new DeleteForumTopicRequest(chatId, messageThreadId), cancellationToken) + .MakeRequestAsync( + new DeleteForumTopicRequest { ChatId = chatId, MessageThreadId = messageThreadId }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -3037,7 +3209,10 @@ public static async Task UnpinAllForumTopicMessagesAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new UnpinAllForumTopicMessagesRequest(chatId, messageThreadId), cancellationToken) + .MakeRequestAsync( + new UnpinAllForumTopicMessagesRequest { ChatId = chatId, MessageThreadId = messageThreadId }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -3061,7 +3236,10 @@ public static async Task EditGeneralForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new EditGeneralForumTopicRequest(chatId, name), cancellationToken) + .MakeRequestAsync( + new EditGeneralForumTopicRequest { ChatId = chatId, Name = name }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -3083,7 +3261,7 @@ public static async Task CloseGeneralForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new CloseGeneralForumTopicRequest(chatId), cancellationToken) + .MakeRequestAsync(new CloseGeneralForumTopicRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -3106,7 +3284,7 @@ public static async Task ReopenGeneralForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new ReopenGeneralForumTopicRequest(chatId), cancellationToken) + .MakeRequestAsync(new ReopenGeneralForumTopicRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -3128,7 +3306,7 @@ public static async Task HideGeneralForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new HideGeneralForumTopicRequest(chatId), cancellationToken) + .MakeRequestAsync(new HideGeneralForumTopicRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -3150,12 +3328,13 @@ public static async Task UnhideGeneralForumTopicAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new UnhideGeneralForumTopicRequest(chatId), cancellationToken) + .MakeRequestAsync(new UnhideGeneralForumTopicRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// - /// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator in - /// the chat for this to work and must have the administrator right in the supergroup. + /// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator + /// in the chat for this to work and must have the + /// administrator right in the supergroup. /// /// An instance of /// @@ -3171,7 +3350,7 @@ public static async Task UnpinAllGeneralForumTopicMessagesAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new UnpinAllGeneralForumTopicMessages(chatId), cancellationToken) + .MakeRequestAsync(new UnpinAllGeneralForumTopicMessages { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -3220,12 +3399,13 @@ public static async Task AnswerCallbackQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerCallbackQueryRequest(callbackQueryId) + new AnswerCallbackQueryRequest { + CallbackQueryId = callbackQueryId, Text = text, ShowAlert = showAlert, Url = url, - CacheTime = cacheTime + CacheTime = cacheTime, }, cancellationToken ) @@ -3253,7 +3433,7 @@ public static async Task GetUserChatBoostsAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetUserChatBoostsRequest(chatId, userId), cancellationToken) + .MakeRequestAsync(new GetUserChatBoostsRequest { ChatId = chatId, UserId = userId }, cancellationToken) .ConfigureAwait(false); /// @@ -3284,10 +3464,11 @@ public static async Task SetMyCommandsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetMyCommandsRequest(commands) + new SetMyCommandsRequest { + Commands = commands, Scope = scope, - LanguageCode = languageCode + LanguageCode = languageCode, }, cancellationToken ) @@ -3319,10 +3500,10 @@ public static async Task DeleteMyCommandsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new DeleteMyCommandsRequest + new DeleteMyCommandsRequest { Scope = scope, - LanguageCode = languageCode + LanguageCode = languageCode, }, cancellationToken ) @@ -3353,10 +3534,10 @@ public static async Task GetMyCommandsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetMyCommandsRequest + new GetMyCommandsRequest { Scope = scope, - LanguageCode = languageCode + LanguageCode = languageCode, }, cancellationToken ) @@ -3384,7 +3565,7 @@ public static async Task SetMyNameAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetMyNameRequest { Name = name, LanguageCode = languageCode }, + new SetMyNameRequest { Name = name, LanguageCode = languageCode }, cancellationToken ) .ConfigureAwait(false); @@ -3409,7 +3590,7 @@ public static async Task GetMyNameAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetMyNameRequest { LanguageCode = languageCode }, + new GetMyNameRequest { LanguageCode = languageCode }, cancellationToken ) .ConfigureAwait(false); @@ -3438,7 +3619,7 @@ public static async Task SetMyDescriptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetMyDescriptionRequest { Description = description, LanguageCode = languageCode }, + new SetMyDescriptionRequest { Description = description, LanguageCode = languageCode }, cancellationToken ) .ConfigureAwait(false); @@ -3464,7 +3645,7 @@ public static async Task GetMyDescriptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetMyDescriptionRequest { LanguageCode = languageCode }, + new GetMyDescriptionRequest { LanguageCode = languageCode }, cancellationToken ) .ConfigureAwait(false); @@ -3494,7 +3675,7 @@ public static async Task SetMyShortDescriptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetMyShortDescriptionRequest + new SetMyShortDescriptionRequest { ShortDescription = shortDescription, LanguageCode = languageCode, @@ -3524,7 +3705,7 @@ public static async Task GetMyShortDescriptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetMyShortDescriptionRequest { LanguageCode = languageCode }, + new GetMyShortDescriptionRequest { LanguageCode = languageCode }, cancellationToken ) .ConfigureAwait(false); @@ -3550,7 +3731,7 @@ public static async Task SetChatMenuButtonAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetChatMenuButtonRequest { ChatId = chatId, MenuButton = menuButton }, + new SetChatMenuButtonRequest { ChatId = chatId, MenuButton = menuButton }, cancellationToken ) .ConfigureAwait(false); @@ -3574,7 +3755,7 @@ public static async Task GetChatMenuButtonAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetChatMenuButtonRequest() { ChatId = chatId }, + new GetChatMenuButtonRequest { ChatId = chatId }, cancellationToken ) .ConfigureAwait(false); @@ -3604,7 +3785,7 @@ public static async Task SetMyDefaultAdministratorRightsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetMyDefaultAdministratorRightsRequest() + new SetMyDefaultAdministratorRightsRequest { Rights = rights, ForChannels = forChannels, @@ -3632,7 +3813,7 @@ public static async Task GetMyDefaultAdministratorRight ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetMyDefaultAdministratorRightsRequest { ForChannels = forChannels }, + new GetMyDefaultAdministratorRightsRequest { ForChannels = forChannels }, cancellationToken ) .ConfigureAwait(false); @@ -3684,12 +3865,15 @@ public static async Task EditMessageTextAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditMessageTextRequest(chatId, messageId, text) + new EditMessageTextRequest { + ChatId = chatId, + MessageId = messageId, + Text = text, ParseMode = parseMode, Entities = entities, LinkPreviewOptions = linkPreviewOptions, - ReplyMarkup = replyMarkup + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3732,12 +3916,14 @@ public static async Task EditMessageTextAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditInlineMessageTextRequest(inlineMessageId, text) + new EditInlineMessageTextRequest { + InlineMessageId = inlineMessageId, + Text = text, ParseMode = parseMode, Entities = entities, LinkPreviewOptions = linkPreviewOptions, - ReplyMarkup = replyMarkup + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3784,12 +3970,14 @@ public static async Task EditMessageCaptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditMessageCaptionRequest(chatId, messageId) + new EditMessageCaptionRequest { + ChatId = chatId, + MessageId = messageId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, - ReplyMarkup = replyMarkup + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3830,12 +4018,13 @@ public static async Task EditMessageCaptionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditInlineMessageCaptionRequest(inlineMessageId) + new EditInlineMessageCaptionRequest { + InlineMessageId = inlineMessageId, Caption = caption, ParseMode = parseMode, CaptionEntities = captionEntities, - ReplyMarkup = replyMarkup + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3874,9 +4063,12 @@ public static async Task EditMessageMediaAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditMessageMediaRequest(chatId, messageId, media) + new EditMessageMediaRequest { - ReplyMarkup = replyMarkup + ChatId = chatId, + MessageId = messageId, + Media = media, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3909,9 +4101,11 @@ public static async Task EditMessageMediaAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditInlineMessageMediaRequest(inlineMessageId, media) + new EditInlineMessageMediaRequest { - ReplyMarkup = replyMarkup + InlineMessageId = inlineMessageId, + Media = media, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3945,9 +4139,11 @@ public static async Task EditMessageReplyMarkupAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditMessageReplyMarkupRequest(chatId, messageId) + new EditMessageReplyMarkupRequest { - ReplyMarkup = replyMarkup + ChatId = chatId, + MessageId = messageId, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -3975,9 +4171,10 @@ public static async Task EditMessageReplyMarkupAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new EditInlineMessageReplyMarkupRequest(inlineMessageId) + new EditInlineMessageReplyMarkupRequest { - ReplyMarkup = replyMarkup + InlineMessageId = inlineMessageId, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -4011,9 +4208,11 @@ public static async Task StopPollAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new StopPollRequest(chatId, messageId) + new StopPollRequest { - ReplyMarkup = replyMarkup + ChatId = chatId, + MessageId = messageId, + ReplyMarkup = replyMarkup, }, cancellationToken ) @@ -4049,7 +4248,7 @@ public static async Task DeleteMessageAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new DeleteMessageRequest(chatId, messageId), cancellationToken) + .MakeRequestAsync(new DeleteMessageRequest { ChatId = chatId, MessageId = messageId }, cancellationToken) .ConfigureAwait(false); /// @@ -4075,7 +4274,10 @@ public static async Task DeleteMessagesAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new DeleteMessagesRequest(chatId, messageIds), cancellationToken) + .MakeRequestAsync( + new DeleteMessagesRequest { ChatId = chatId, MessageIds = messageIds }, + cancellationToken + ) .ConfigureAwait(false); #endregion Updating messages @@ -4139,8 +4341,10 @@ public static async Task SendStickerAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendStickerRequest(chatId, sticker) + new SendStickerRequest { + ChatId = chatId, + Sticker = sticker, MessageThreadId = messageThreadId, Emoji = emoji, DisableNotification = disableNotification, @@ -4148,7 +4352,7 @@ await botClient.ThrowIfNull() ReplyParameters = replyParameters, ReplyMarkup = replyMarkup, }, - cancellationToken: cancellationToken + cancellationToken ) .ConfigureAwait(false); @@ -4173,10 +4377,7 @@ public static async Task GetStickerSetAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync( - request: new GetStickerSetRequest(name), - cancellationToken: cancellationToken - ) + .MakeRequestAsync(new GetStickerSetRequest { Name = name }, cancellationToken) .ConfigureAwait(false); /// @@ -4197,8 +4398,8 @@ public static async Task GetCustomEmojiStickersAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetCustomEmojiStickersRequest(customEmojiIds), - cancellationToken: cancellationToken + new GetCustomEmojiStickersRequest { CustomEmojiIds = customEmojiIds }, + cancellationToken ) .ConfigureAwait(false); @@ -4234,8 +4435,13 @@ public static async Task UploadStickerFileAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new UploadStickerFileRequest(userId, sticker, stickerFormat), - cancellationToken: cancellationToken + new UploadStickerFileRequest + { + UserId = userId, + Sticker = sticker, + StickerFormat = stickerFormat, + }, + cancellationToken ) .ConfigureAwait(false); @@ -4289,12 +4495,17 @@ public static async Task CreateNewStickerSetAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new CreateNewStickerSetRequest(userId, name, title, stickers, stickerFormat) + new CreateNewStickerSetRequest { + UserId = userId, + Name = name, + Title = title, + Stickers = stickers, + StickerFormat = stickerFormat, NeedsRepainting = needsRepainting, StickerType = stickerType, }, - cancellationToken: cancellationToken + cancellationToken ) .ConfigureAwait(false); @@ -4338,8 +4549,8 @@ public static async Task AddStickerToSetAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AddStickerToSetRequest(userId, name, sticker), - cancellationToken: cancellationToken + new AddStickerToSetRequest { UserId = userId, Name = name, Sticker = sticker, }, + cancellationToken ) .ConfigureAwait(false); @@ -4362,8 +4573,8 @@ public static async Task SetStickerPositionInSetAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerPositionInSetRequest(sticker, position), - cancellationToken: cancellationToken + new SetStickerPositionInSetRequest { Sticker = sticker, Position = position, }, + cancellationToken ) .ConfigureAwait(false); @@ -4384,8 +4595,8 @@ public static async Task DeleteStickerFromSetAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new DeleteStickerFromSetRequest(sticker), - cancellationToken: cancellationToken + new DeleteStickerFromSetRequest { Sticker = sticker }, + cancellationToken ) .ConfigureAwait(false); @@ -4413,8 +4624,8 @@ public static async Task SetStickerEmojiListAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerEmojiListRequest(sticker, emojiList), - cancellationToken: cancellationToken + new SetStickerEmojiListRequest { Sticker = sticker, EmojiList = emojiList }, + cancellationToken ) .ConfigureAwait(false); @@ -4443,11 +4654,8 @@ public static async Task SetStickerKeywordsAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerKeywordsRequest(sticker) - { - Keywords = keywords, - }, - cancellationToken: cancellationToken + new SetStickerKeywordsRequest { Sticker = sticker, Keywords = keywords, }, + cancellationToken ) .ConfigureAwait(false); @@ -4476,8 +4684,8 @@ public static async Task SetStickerMaskPositionAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerMaskPositionRequest(sticker) { MaskPosition = maskPosition }, - cancellationToken: cancellationToken + new SetStickerMaskPositionRequest { Sticker = sticker, MaskPosition = maskPosition }, + cancellationToken ) .ConfigureAwait(false); @@ -4504,8 +4712,8 @@ public static async Task SetStickerSetTitleAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerSetTitleRequest(name, title), - cancellationToken: cancellationToken + new SetStickerSetTitleRequest { Name = name, Title = title }, + cancellationToken ) .ConfigureAwait(false); @@ -4546,11 +4754,8 @@ public static async Task SetStickerSetThumbnailAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetStickerSetThumbnailRequest(name, userId) - { - Thumbnail = thumbnail, - }, - cancellationToken: cancellationToken + new SetStickerSetThumbnailRequest { Name = name, UserId = userId, Thumbnail = thumbnail }, + cancellationToken ) .ConfigureAwait(false); @@ -4578,11 +4783,8 @@ public static async Task SetCustomEmojiStickerSetThumbnailAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetCustomEmojiStickerSetThumbnailRequest(name) - { - CustomEmojiId = customEmojiId, - }, - cancellationToken: cancellationToken + new SetCustomEmojiStickerSetThumbnailRequest { Name = name, CustomEmojiId = customEmojiId }, + cancellationToken ) .ConfigureAwait(false); @@ -4604,10 +4806,7 @@ public static async Task DeleteStickerSetAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync( - request: new DeleteStickerSetRequest(name), - cancellationToken: cancellationToken - ) + .MakeRequestAsync(new DeleteStickerSetRequest { Name = name }, cancellationToken) .ConfigureAwait(false); #endregion @@ -4653,8 +4852,10 @@ public static async Task AnswerInlineQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerInlineQueryRequest(inlineQueryId, results) + new AnswerInlineQueryRequest { + InlineQueryId = inlineQueryId, + Results = results, CacheTime = cacheTime, IsPersonal = isPersonal, NextOffset = nextOffset, @@ -4685,7 +4886,7 @@ public static async Task AnswerWebAppQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerWebAppQueryRequest(webAppQueryId, result), + new AnswerWebAppQueryRequest { WebAppQueryId = webAppQueryId, Result = result }, cancellationToken ) .ConfigureAwait(false); @@ -4815,16 +5016,15 @@ public static async Task SendInvoiceAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendInvoiceRequest( - chatId, - title, - description, - payload, - providerToken, - currency, - // ReSharper disable once PossibleMultipleEnumeration - prices) + new SendInvoiceRequest { + ChatId = chatId, + Title = title, + Description = description, + Payload = payload, + ProviderToken = providerToken, + Currency = currency, + Prices = prices, MessageThreadId = messageThreadId, MaxTipAmount = maxTipAmount, SuggestedTipAmounts = suggestedTipAmounts, @@ -4939,15 +5139,14 @@ public static async Task CreateInvoiceLinkAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new CreateInvoiceLinkRequest( - title, - description, - payload, - providerToken, - currency, - // ReSharper disable once PossibleMultipleEnumeration - prices) + new CreateInvoiceLinkRequest { + Title = title, + Description = description, + Payload = payload, + ProviderToken = providerToken, + Currency = currency, + Prices = prices, MaxTipAmount = maxTipAmount, SuggestedTipAmounts = suggestedTipAmounts, ProviderData = providerData, @@ -4961,7 +5160,7 @@ await botClient.ThrowIfNull() NeedShippingAddress = needShippingAddress, SendPhoneNumberToProvider = sendPhoneNumberToProvider, SendEmailToProvider = sendEmailToProvider, - IsFlexible = isFlexible + IsFlexible = isFlexible, }, cancellationToken ) @@ -4988,7 +5187,7 @@ public static async Task AnswerShippingQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerShippingQueryRequest(shippingQueryId, shippingOptions), + new AnswerShippingQueryRequest(shippingQueryId, shippingOptions), cancellationToken ) .ConfigureAwait(false); @@ -5016,7 +5215,7 @@ public static async Task AnswerShippingQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerShippingQueryRequest(shippingQueryId, errorMessage), + new AnswerShippingQueryRequest(shippingQueryId, errorMessage), cancellationToken ) .ConfigureAwait(false); @@ -5040,7 +5239,7 @@ public static async Task AnswerPreCheckoutQueryAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new AnswerPreCheckoutQueryRequest(preCheckoutQueryId), cancellationToken) + .MakeRequestAsync(new AnswerPreCheckoutQueryRequest(preCheckoutQueryId), cancellationToken) .ConfigureAwait(false); /// @@ -5067,7 +5266,7 @@ public static async Task AnswerPreCheckoutQueryAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new AnswerPreCheckoutQueryRequest(preCheckoutQueryId, errorMessage), + new AnswerPreCheckoutQueryRequest(preCheckoutQueryId, errorMessage), cancellationToken ) .ConfigureAwait(false); @@ -5081,10 +5280,10 @@ await botClient.ThrowIfNull() /// /// An instance of /// Unique identifier for the target chat - /// /// /// Unique identifier for the target message thread (topic) of the forum; for forum supergroups only /// + /// /// Short name of the game, serves as the unique identifier for the game. Set up your games via /// @BotFather /// @@ -5116,8 +5315,10 @@ public static async Task SendGameAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SendGameRequest(chatId, gameShortName) + new SendGameRequest { + ChatId = chatId, + GameShortName = gameShortName, MessageThreadId = messageThreadId, DisableNotification = disableNotification, ProtectContent = protectContent, @@ -5162,10 +5363,14 @@ public static async Task SetGameScoreAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetGameScoreRequest(userId, score, chatId, messageId) + new SetGameScoreRequest { + UserId = userId, + Score = score, + ChatId = chatId, + MessageId = messageId, Force = force, - DisableEditMessage = disableEditMessage + DisableEditMessage = disableEditMessage, }, cancellationToken ) @@ -5203,10 +5408,13 @@ public static async Task SetGameScoreAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new SetInlineGameScoreRequest(userId, score, inlineMessageId) + new SetInlineGameScoreRequest { + UserId = userId, + Score = score, + InlineMessageId = inlineMessageId, Force = force, - DisableEditMessage = disableEditMessage + DisableEditMessage = disableEditMessage, }, cancellationToken ) @@ -5237,7 +5445,15 @@ public static async Task GetGameHighScoresAsync( CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(request: new GetGameHighScoresRequest(userId, chatId, messageId), cancellationToken) + .MakeRequestAsync( + new GetGameHighScoresRequest + { + ChatId = chatId, + UserId = userId, + MessageId = messageId, + }, + cancellationToken + ) .ConfigureAwait(false); /// @@ -5264,7 +5480,7 @@ public static async Task GetGameHighScoresAsync( ) => await botClient.ThrowIfNull() .MakeRequestAsync( - request: new GetInlineGameHighScoresRequest(userId, inlineMessageId), + new GetInlineGameHighScoresRequest { UserId = userId, InlineMessageId = inlineMessageId }, cancellationToken ) .ConfigureAwait(false); diff --git a/src/Telegram.Bot/Types/Color.cs b/src/Telegram.Bot/Types/Color.cs index ecb637ea7..8caf2e862 100644 --- a/src/Telegram.Bot/Types/Color.cs +++ b/src/Telegram.Bot/Types/Color.cs @@ -85,7 +85,7 @@ public Color(int color) /// public Color(uint color) { - if (color is > MaxRgbValue or < 0) + if (color is > MaxRgbValue) { throw new ArgumentOutOfRangeException(nameof(color), color, "Color is out of range"); } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs index df9fc6979..7e3373c51 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.ReplyMarkups; // ReSharper disable once CheckNamespace @@ -19,7 +20,7 @@ public abstract class InlineQueryResult /// Unique identifier for this result, 1-64 Bytes /// [JsonProperty(Required = Required.Always)] - public string Id { get; } + public required string Id { get; init; } /// /// Optional. Inline keyboard attached to the message @@ -31,5 +32,13 @@ public abstract class InlineQueryResult /// Initializes a new inline query result /// /// Unique identifier for this result, 1-64 Bytes + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] protected InlineQueryResult(string id) => Id = id; + + /// + /// Initializes a new inline query result + /// + protected InlineQueryResult() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs index 3df212960..4b36590e8 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -19,13 +19,13 @@ public class InlineQueryResultArticle : InlineQueryResult /// Title of the result /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Content of the message to be sent /// [JsonProperty(Required = Required.Always)] - public InputMessageContent InputMessageContent { get; } + public required InputMessageContent InputMessageContent { get; init; } /// /// Optional. URL of the result. @@ -63,10 +63,18 @@ public class InlineQueryResultArticle : InlineQueryResult /// Unique identifier of this result /// Title of the result /// Content of the message to be sent + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultArticle(string id, string title, InputMessageContent inputMessageContent) : base(id) { Title = title; InputMessageContent = inputMessageContent; } + + /// + /// Initializes a new object + /// + public InlineQueryResultArticle() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs index 3f7e8b639..580746864 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -21,13 +22,13 @@ public class InlineQueryResultAudio : InlineQueryResult /// A valid URL for the audio file /// [JsonProperty(Required = Required.Always)] - public string AudioUrl { get; } + public required string AudioUrl { get; init; } /// /// Title /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -63,10 +64,18 @@ public class InlineQueryResultAudio : InlineQueryResult /// Unique identifier of this result /// A valid URL for the audio file /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultAudio(string id, string audioUrl, string title) : base(id) { AudioUrl = audioUrl; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultAudio() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs index 501fbc610..a7ccdab6f 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultCachedAudio : InlineQueryResult /// A valid file identifier for the audio file /// [JsonProperty(Required = Required.Always)] - public string AudioFileId { get; } + public required string AudioFileId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -45,9 +46,17 @@ public class InlineQueryResultCachedAudio : InlineQueryResult /// /// Unique identifier of this result /// A valid file identifier for the audio file + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedAudio(string id, string audioFileId) : base(id) { AudioFileId = audioFileId; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedAudio() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs index 5294f0046..190aaee85 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,13 +23,13 @@ public class InlineQueryResultCachedDocument : InlineQueryResult /// Title for the result /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// A valid file identifier for the file /// [JsonProperty(Required = Required.Always)] - public string DocumentFileId { get; } + public required string DocumentFileId { get; init; } /// /// Optional. Short description of the result @@ -58,10 +59,18 @@ public class InlineQueryResultCachedDocument : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the file /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedDocument(string id, string documentFileId, string title) : base(id) { DocumentFileId = documentFileId; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedDocument() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs index 0bac4d871..c19dba568 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultCachedGif : InlineQueryResult /// A valid file identifier for the GIF file /// [JsonProperty(Required = Required.Always)] - public string GifFileId { get; } + public required string GifFileId { get; init; } /// /// Optional. Title for the result @@ -51,9 +52,17 @@ public class InlineQueryResultCachedGif : InlineQueryResult /// /// Unique identifier of this result /// A valid file identifier for the GIF file + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedGif(string id, string gifFileId) : base(id) { GifFileId = gifFileId; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedGif() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs index 725134fcd..36ecff411 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -23,7 +24,7 @@ public class InlineQueryResultCachedMpeg4Gif : InlineQueryResult /// A valid file identifier for the MP4 file /// [JsonProperty(Required = Required.Always)] - public string Mpeg4FileId { get; } + public required string Mpeg4FileId { get; init; } /// /// Optional. Title for the result @@ -52,9 +53,17 @@ public class InlineQueryResultCachedMpeg4Gif : InlineQueryResult /// /// Unique identifier of this result /// A valid file identifier for the MP4 file + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedMpeg4Gif(string id, string mpeg4FileId) : base(id) { Mpeg4FileId = mpeg4FileId; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedMpeg4Gif() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs index 542eeeb75..0901729a4 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultCachedPhoto : InlineQueryResult /// A valid file identifier of the photo /// [JsonProperty(Required = Required.Always)] - public string PhotoFileId { get; } + public required string PhotoFileId { get; init; } /// /// Optional. Title for the result @@ -57,9 +58,17 @@ public class InlineQueryResultCachedPhoto : InlineQueryResult /// /// Unique identifier of this result /// A valid file identifier of the photo + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedPhoto(string id, string photoFileId) : base(id) { PhotoFileId = photoFileId; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedPhoto() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs index ed4f1cb8e..740d56572 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -22,7 +22,7 @@ public class InlineQueryResultCachedSticker : InlineQueryResult /// A valid file identifier of the sticker /// [JsonProperty(Required = Required.Always)] - public string StickerFileId { get; } + public required string StickerFileId { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -33,9 +33,17 @@ public class InlineQueryResultCachedSticker : InlineQueryResult /// /// Unique identifier of this result /// A valid file identifier of the sticker + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedSticker(string id, string stickerFileId) : base(id) { StickerFileId = stickerFileId; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedSticker() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs index 9bef333d5..f1ba4ece7 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,13 +23,13 @@ public class InlineQueryResultCachedVideo : InlineQueryResult /// A valid file identifier for the video file /// [JsonProperty(Required = Required.Always)] - public string VideoFileId { get; } + public required string VideoFileId { get; init; } /// /// Title for the result /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Optional. Short description of the result @@ -58,10 +59,18 @@ public class InlineQueryResultCachedVideo : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the video file /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedVideo(string id, string videoFileId, string title) : base(id) { VideoFileId = videoFileId; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedVideo() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs index 700208f0d..be4fa3cce 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,13 +23,13 @@ public class InlineQueryResultCachedVoice : InlineQueryResult /// A valid file identifier for the voice message /// [JsonProperty(Required = Required.Always)] - public string VoiceFileId { get; } + public required string VoiceFileId { get; init; } /// /// Voice message title /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -52,10 +53,18 @@ public class InlineQueryResultCachedVoice : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the voice message /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultCachedVoice(string id, string fileId, string title) : base(id) { VoiceFileId = fileId; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultCachedVoice() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs index a953c1c1f..554bd1cbf 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -21,13 +21,13 @@ public class InlineQueryResultContact : InlineQueryResult /// Contact's phone number /// [JsonProperty(Required = Required.Always)] - public string PhoneNumber { get; } + public required string PhoneNumber { get; init; } /// /// Contact's first name /// [JsonProperty(Required = Required.Always)] - public string FirstName { get; } + public required string FirstName { get; init; } /// /// Optional. Contact's last name @@ -63,10 +63,18 @@ public class InlineQueryResultContact : InlineQueryResult /// Unique identifier of this result /// Contact's phone number /// Contact's first name + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultContact(string id, string phoneNumber, string firstName) : base(id) { PhoneNumber = phoneNumber; FirstName = firstName; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultContact() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs index 2dd53a93d..5b18e2164 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultDocument : InlineQueryResult /// Title for the result /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -40,13 +41,13 @@ public class InlineQueryResultDocument : InlineQueryResult /// A valid URL for the file /// [JsonProperty(Required = Required.Always)] - public string DocumentUrl { get; } + public required string DocumentUrl { get; init; } /// /// Mime type of the content of the file, either “application/pdf” or “application/zip” /// [JsonProperty(Required = Required.Always)] - public string MimeType { get; } + public required string MimeType { get; init; } /// /// Optional. Short description of the result @@ -79,6 +80,8 @@ public class InlineQueryResultDocument : InlineQueryResult /// /// Mime type of the content of the file, either “application/pdf” or “application/zip” /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultDocument(string id, string documentUrl, string title, string mimeType) : base(id) { @@ -86,4 +89,10 @@ public InlineQueryResultDocument(string id, string documentUrl, string title, st Title = title; MimeType = mimeType; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultDocument() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs index 747be7605..3b2d438d5 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -19,16 +19,24 @@ public class InlineQueryResultGame : InlineQueryResult /// Short name of the game /// [JsonProperty(Required = Required.Always)] - public string GameShortName { get; } + public required string GameShortName { get; init; } /// /// Initializes a new inline query result /// /// Unique identifier of this result /// Short name of the game + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultGame(string id, string gameShortName) : base(id) { GameShortName = gameShortName; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultGame() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs index c7cba9940..dd9849472 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultGif : InlineQueryResult /// A valid URL for the GIF file. File size must not exceed 1MB /// [JsonProperty(Required = Required.Always)] - public string GifUrl { get; } + public required string GifUrl { get; init; } /// /// Optional. Width of the GIF. @@ -46,7 +47,7 @@ public class InlineQueryResultGif : InlineQueryResult /// URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result /// [JsonProperty(Required = Required.Always)] - public string ThumbnailUrl { get; } + public required string ThumbnailUrl { get; init; } /// /// Optional. MIME type of the thumbnail, must be one of “image/jpeg”, “image/gif”, @@ -83,10 +84,18 @@ public class InlineQueryResultGif : InlineQueryResult /// Unique identifier of this result /// Width of the GIF /// Url of the thumbnail for the result. + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultGif(string id, string gifUrl, string thumbnailUrl) : base(id) { GifUrl = gifUrl; ThumbnailUrl = thumbnailUrl; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultGif() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs index 7226b1307..d60dac166 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -19,17 +19,17 @@ public class InlineQueryResultLocation : InlineQueryResult /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// Location title /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Optional. The radius of uncertainty for the location, measured in meters; 0-1500 @@ -80,6 +80,8 @@ public class InlineQueryResultLocation : InlineQueryResult /// Latitude of the location in degrees /// Longitude of the location in degrees /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultLocation(string id, double latitude, double longitude, string title) : base(id) { @@ -87,4 +89,10 @@ public InlineQueryResultLocation(string id, double latitude, double longitude, s Longitude = longitude; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultLocation() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs index 2fb39947f..df315bd74 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,7 +23,7 @@ public class InlineQueryResultMpeg4Gif : InlineQueryResult /// A valid URL for the MP4 file. File size must not exceed 1MB /// [JsonProperty(Required = Required.Always)] - public string Mpeg4Url { get; } + public required string Mpeg4Url { get; init; } /// /// Optional. Video width @@ -46,7 +47,7 @@ public class InlineQueryResultMpeg4Gif : InlineQueryResult /// URL of the static (JPEG or GIF) or animated (MPEG4) thumbnail for the result /// [JsonProperty(Required = Required.Always)] - public string ThumbnailUrl { get; } + public required string ThumbnailUrl { get; init; } /// /// Optional. MIME type of the thumbnail, must be one of “image/jpeg”, “image/gif”, @@ -83,10 +84,18 @@ public class InlineQueryResultMpeg4Gif : InlineQueryResult /// Unique identifier of this result /// A valid URL for the MP4 file. File size must not exceed 1MB. /// Url of the thumbnail for the result. + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultMpeg4Gif(string id, string mpeg4Url, string thumbnailUrl) : base(id) { Mpeg4Url = mpeg4Url; ThumbnailUrl = thumbnailUrl; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultMpeg4Gif() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs index 8af55ed21..8993fb4d1 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -21,11 +22,11 @@ public class InlineQueryResultPhoto : InlineQueryResult /// A valid URL of the photo. Photo must be in jpeg format. Photo size must not exceed 5MB /// [JsonProperty(Required = Required.Always)] - public string PhotoUrl { get; } + public required string PhotoUrl { get; init; } /// [JsonProperty(Required = Required.Always)] - public string ThumbnailUrl { get; } + public required string ThumbnailUrl { get; init; } /// /// Optional. Width of the photo @@ -73,10 +74,18 @@ public class InlineQueryResultPhoto : InlineQueryResult /// Unique identifier of this result /// A valid URL of the photo. Photo size must not exceed 5MB. /// Optional. Url of the thumbnail for the result. + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultPhoto(string id, string photoUrl, string thumbnailUrl) : base(id) { PhotoUrl = photoUrl; ThumbnailUrl = thumbnailUrl; } + + /// + /// Initializes a new inline query representing a link to a photo + /// + public InlineQueryResultPhoto() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs index 654dd27fc..858c5dce1 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -19,23 +19,23 @@ public class InlineQueryResultVenue : InlineQueryResult /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// Title of the venue /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Address of the venue /// [JsonProperty(Required = Required.Always)] - public string Address { get; } + public required string Address { get; init; } /// /// Optional. Foursquare identifier of the venue if known @@ -87,6 +87,8 @@ public class InlineQueryResultVenue : InlineQueryResult /// Longitude of the location in degrees /// Title of the result /// Address of the venue + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultVenue( string id, double latitude, @@ -99,4 +101,10 @@ public InlineQueryResultVenue( Title = title; Address = address; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultVenue() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs index c0596a7ed..0aad047b9 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -26,25 +27,25 @@ public class InlineQueryResultVideo : InlineQueryResult /// A valid URL for the embedded video player or video file /// [JsonProperty(Required = Required.Always)] - public string VideoUrl { get; } + public required string VideoUrl { get; init; } /// /// Mime type of the content of video url, “text/html” or “video/mp4” /// [JsonProperty(Required = Required.Always)] - public string MimeType { get; } + public required string MimeType { get; init; } /// /// URL of the thumbnail (jpeg only) for the video /// [JsonProperty(Required = Required.Always)] - public string ThumbnailUrl { get; } + public required string ThumbnailUrl { get; init; } /// /// Title for the result /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -102,6 +103,8 @@ public class InlineQueryResultVideo : InlineQueryResult /// is used to send an HTML-page as a result /// (e.g., a YouTube video). /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultVideo( string id, string videoUrl, @@ -115,4 +118,10 @@ public InlineQueryResultVideo( Title = title; InputMessageContent = inputMessageContent; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultVideo() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs index ba8dec565..7ae68b7e6 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -22,13 +23,13 @@ public class InlineQueryResultVoice : InlineQueryResult /// A valid URL for the voice recording /// [JsonProperty(Required = Required.Always)] - public string VoiceUrl { get; } + public required string VoiceUrl { get; init; } /// /// Recording title /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] @@ -58,10 +59,18 @@ public class InlineQueryResultVoice : InlineQueryResult /// Unique identifier of this result /// A valid URL for the voice recording /// Title of the result + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InlineQueryResultVoice(string id, string voiceUrl, string title) : base(id) { VoiceUrl = voiceUrl; Title = title; } + + /// + /// Initializes a new inline query result + /// + public InlineQueryResultVoice() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultsButton.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultsButton.cs index bf6d554da..214bc4b33 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultsButton.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultsButton.cs @@ -12,7 +12,7 @@ public class InlineQueryResultsButton /// Label text on the button /// [JsonProperty(Required = Required.Always)] - public string Text { get; } + public required string Text { get; init; } /// /// Optional. Description of the Web App that will be launched when the user presses @@ -49,4 +49,10 @@ public InlineQueryResultsButton(string text) { Text = text; } + + /// + /// Initializes a new object + /// + public InlineQueryResultsButton() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs index ac6833554..3719997fb 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -13,13 +13,13 @@ public class InputContactMessageContent : InputMessageContent /// Contact's phone number /// [JsonProperty(Required = Required.Always)] - public string PhoneNumber { get; } + public required string PhoneNumber { get; init; } /// /// Contact's first name /// [JsonProperty(Required = Required.Always)] - public string FirstName { get; } + public required string FirstName { get; init; } /// /// Optional. Contact's last name @@ -38,9 +38,17 @@ public class InputContactMessageContent : InputMessageContent /// /// The phone number of the contact /// The first name of the contact + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputContactMessageContent(string phoneNumber, string firstName) { PhoneNumber = phoneNumber; FirstName = firstName; } + + /// + /// Initializes a new input contact message content + /// + public InputContactMessageContent() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs index 6520b811a..49cca0b5e 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Payments; // ReSharper disable once CheckNamespace @@ -15,40 +16,40 @@ public class InputInvoiceMessageContent : InputMessageContent /// Product name, 1-32 characters /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Product description, 1-255 characters /// [JsonProperty(Required = Required.Always)] - public string Description { get; } + public required string Description { get; init; } /// /// Bot-defined invoice payload, 1-128 bytes. This will not be displayed to the user, /// use for your internal processes. /// [JsonProperty(Required = Required.Always)] - public string Payload { get; } + public required string Payload { get; init; } /// /// Payment provider token, obtained via @BotFather /// [JsonProperty(Required = Required.Always)] - public string ProviderToken { get; } + public required string ProviderToken { get; init; } /// /// Three-letter ISO 4217 currency code, see /// more on currencies /// [JsonProperty(Required = Required.Always)] - public string Currency { get; } + public required string Currency { get; init; } /// /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// [JsonProperty(Required = Required.Always)] - public IEnumerable Prices { get; } + public required IEnumerable Prices { get; init; } /// /// Optional. The maximum accepted amount for tips in the smallest units of the currency @@ -158,6 +159,8 @@ public class InputInvoiceMessageContent : InputMessageContent /// Price breakdown, a list of components (e.g. product price, tax, discount, delivery cost, /// delivery tax, bonus, etc.) /// + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputInvoiceMessageContent( string title, string description, @@ -173,4 +176,10 @@ public InputInvoiceMessageContent( Currency = currency; Prices = prices; } + + /// + /// Initializes a new input message content + /// + public InputInvoiceMessageContent() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs index 0174dbfbe..77e215f98 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -14,13 +14,13 @@ public class InputLocationMessageContent : InputMessageContent /// Latitude of the location in degrees /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of the location in degrees /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// Optional. The radius of uncertainty for the location, measured in meters; 0-1500 @@ -52,9 +52,17 @@ public class InputLocationMessageContent : InputMessageContent /// /// The latitude of the location /// The longitude of the location + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputLocationMessageContent(double latitude, double longitude) { Latitude = latitude; Longitude = longitude; } + + /// + /// Initializes a new input location message content + /// + public InputLocationMessageContent() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs index 5d5871d3b..c82e75490 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputMessageContent.cs @@ -1,5 +1,3 @@ - - // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs index 5e521492e..b98d4cdb9 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -14,7 +15,7 @@ public class InputTextMessageContent : InputMessageContent /// Text of the message to be sent, 1-4096 characters /// [JsonProperty(Required = Required.Always)] - public string MessageText { get; } + public required string MessageText { get; init; } /// /// Optional. Mode for @@ -41,8 +42,16 @@ public class InputTextMessageContent : InputMessageContent /// Initializes a new input text message content /// /// The text of the message + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputTextMessageContent(string messageText) { MessageText = messageText; } + + /// + /// Initializes a new input text message content + /// + public InputTextMessageContent() + { } } diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs index e36f4860f..b9f7086b3 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs @@ -1,4 +1,4 @@ - +using System.Diagnostics.CodeAnalysis; // ReSharper disable once CheckNamespace namespace Telegram.Bot.Types.InlineQueryResults; @@ -14,25 +14,25 @@ public class InputVenueMessageContent : InputMessageContent /// Latitude of the venue in degrees /// [JsonProperty(Required = Required.Always)] - public double Latitude { get; } + public required double Latitude { get; init; } /// /// Longitude of the venue in degrees /// [JsonProperty(Required = Required.Always)] - public double Longitude { get; } + public required double Longitude { get; init; } /// /// Name of the venue /// [JsonProperty(Required = Required.Always)] - public string Title { get; } + public required string Title { get; init; } /// /// Address of the venue /// [JsonProperty(Required = Required.Always)] - public string Address { get; } + public required string Address { get; init; } /// /// Optional. Foursquare identifier of the venue, if known @@ -67,6 +67,8 @@ public class InputVenueMessageContent : InputMessageContent /// The address of the venue /// The latitude of the venue /// The longitude of the venue + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputVenueMessageContent(string title, string address, double latitude, double longitude) { Title = title; @@ -74,4 +76,10 @@ public InputVenueMessageContent(string title, string address, double latitude, d Latitude = latitude; Longitude = longitude; } + + /// + /// Initializes a new inline query result + /// + public InputVenueMessageContent() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputFileId.cs b/src/Telegram.Bot/Types/InputFiles/InputFileId.cs index 658986544..67c9aacce 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputFileId.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputFileId.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -14,11 +15,19 @@ public class InputFileId : InputFile /// /// A file identifier /// - public string Id { get; } + public required string Id { get; init; } + + /// + /// This object represents a file that is already stored somewhere on the Telegram servers + /// + public InputFileId() + {} /// /// This object represents a file that is already stored somewhere on the Telegram servers /// /// A file identifier - public InputFileId(string id) => Id = id; + [SetsRequiredMembers] + public InputFileId(string id) + => Id = id; } diff --git a/src/Telegram.Bot/Types/InputFiles/InputFileStream.cs b/src/Telegram.Bot/Types/InputFiles/InputFileStream.cs index 4c065af4d..fc3f1cbfb 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputFileStream.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputFileStream.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using System.IO; using Telegram.Bot.Types.Enums; @@ -16,7 +17,7 @@ public class InputFileStream : InputFile /// /// File content to upload /// - public Stream Content { get; } + public required Stream Content { get; init; } /// /// Name of a file to upload using multipart/form-data @@ -29,6 +30,14 @@ public class InputFileStream : InputFile /// /// File content to upload /// Name of a file to upload using multipart/form-data + [SetsRequiredMembers] public InputFileStream(Stream content, string? fileName = default) => (Content, FileName) = (content, fileName); + + /// + /// This object represents the contents of a file to be uploaded. Must be posted using multipart/form-data + /// in the usual way that files are uploaded via the browser. + /// + public InputFileStream() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputFileUrl.cs b/src/Telegram.Bot/Types/InputFiles/InputFileUrl.cs index b2f078fdd..22d6b0a0d 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputFileUrl.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputFileUrl.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -14,17 +15,27 @@ public class InputFileUrl : InputFile /// /// HTTP URL for the file to be sent /// - public Uri Url { get; } + public required Uri Url { get; init; } /// /// This object represents an HTTP URL for the file to be sent /// /// HTTP URL for the file to be sent - public InputFileUrl(string url) => Url = new(url); + [SetsRequiredMembers] + public InputFileUrl(string url) + => Url = new(url); /// /// This object represents an HTTP URL for the file to be sent /// /// HTTP URL for the file to be sent - public InputFileUrl(Uri uri) => Url = uri; + [SetsRequiredMembers] + public InputFileUrl(Uri uri) + => Url = uri; + + /// + /// This object represents an HTTP URL for the file to be sent + /// + public InputFileUrl() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs index 7e032b79a..4d07152a2 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -21,7 +22,7 @@ public abstract class InputMedia /// to upload a new one using multipart/form-data under <file_attach_name%gt; name. /// [JsonProperty(Required = Required.Always)] - public InputFile Media { get; } + public required InputFile Media { get; init; } /// /// Optional. Caption of the photo to be sent, 0-1024 characters @@ -46,5 +47,13 @@ public abstract class InputMedia /// Initialize an object /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] protected InputMedia(InputFile media) => Media = media; + + /// + /// Initialize an object + /// + protected InputMedia() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs index a4965630e..535eceb16 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -47,7 +48,15 @@ public class InputMediaAnimation : /// Initializes a new animation media to send with an /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputMediaAnimation(InputFile media) : base(media) { } + + /// + /// Initializes a new animation media to send with an + /// + public InputMediaAnimation() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs index 00bade1b2..3d84bf209 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -42,7 +43,15 @@ public class InputMediaAudio : /// Initializes a new audio media to send with an /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputMediaAudio(InputFile media) : base(media) { } + + /// + /// Initializes a new audio media to send with an + /// + public InputMediaAudio() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs index c94ac9761..7072a9f07 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -31,7 +32,15 @@ public class InputMediaDocument : /// Initializes a new document media to send with an /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputMediaDocument(InputFile media) : base(media) { } + + /// + /// Initializes a new document media to send with an + /// + public InputMediaDocument() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs index c31ec9a59..4781b950c 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -24,7 +25,15 @@ public class InputMediaPhoto : /// Initializes a new photo media to send with an /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputMediaPhoto(InputFile media) : base(media) { } + + /// + /// Initializes a new photo media to send with an + /// + public InputMediaPhoto() + { } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs index 670304451..41f832568 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs @@ -1,3 +1,4 @@ +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; // ReSharper disable once CheckNamespace @@ -54,7 +55,15 @@ public class InputMediaVideo : /// Initializes a new video media to send with an /// /// File to send + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required parameters")] public InputMediaVideo(InputFile media) : base(media) { } + + /// + /// Initializes a new video media to send with an + /// + public InputMediaVideo() + { } } diff --git a/src/Telegram.Bot/Types/InputSticker.cs b/src/Telegram.Bot/Types/InputSticker.cs index aa893e57b..4da5f8cf3 100644 --- a/src/Telegram.Bot/Types/InputSticker.cs +++ b/src/Telegram.Bot/Types/InputSticker.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Types; @@ -19,13 +20,13 @@ public class InputSticker /// If you are using a , then the property is required. /// [JsonProperty(Required = Required.Always)] - public InputFile Sticker { get; } + public required InputFile Sticker { get; init; } /// /// List of 1-20 emoji associated with the sticker /// [JsonProperty(Required = Required.Always)] - public IEnumerable EmojiList { get; } + public required IEnumerable EmojiList { get; init; } /// /// Optional. Position where the mask should be placed on faces. @@ -55,9 +56,16 @@ public class InputSticker /// /// List of 1-20 emoji associated with the sticker /// + [SetsRequiredMembers] public InputSticker(InputFile sticker, IEnumerable emojiList) { Sticker = sticker; EmojiList = emojiList; } + + /// + /// Initializes a new input sticker to create or add sticker sets + /// + public InputSticker() + { } } diff --git a/src/Telegram.Bot/Types/Payments/LabeledPrice.cs b/src/Telegram.Bot/Types/Payments/LabeledPrice.cs index 3d69e143c..f575c7fb4 100644 --- a/src/Telegram.Bot/Types/Payments/LabeledPrice.cs +++ b/src/Telegram.Bot/Types/Payments/LabeledPrice.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types.Payments; /// @@ -11,7 +13,7 @@ public class LabeledPrice /// Portion label /// [JsonProperty(Required = Required.Always)] - public string Label { get; set; } + public required string Label { get; init; } /// /// Price of the product in the smallest units of the @@ -24,7 +26,7 @@ public class LabeledPrice /// /// [JsonProperty(Required = Required.Always)] - public int Amount { get; set; } + public required int Amount { get; init; } /// /// Initializes an instance of @@ -32,9 +34,16 @@ public class LabeledPrice /// Portion label /// Price of the product [JsonConstructor] + [SetsRequiredMembers] public LabeledPrice(string label, int amount) { Label = label; Amount = amount; } + + /// + /// Initializes an instance of + /// + public LabeledPrice() + { } } diff --git a/src/Telegram.Bot/Types/ReplyMarkups/IKeyboardButton.cs b/src/Telegram.Bot/Types/ReplyMarkups/IKeyboardButton.cs index 8bbeb1fb9..9cf582698 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/IKeyboardButton.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/IKeyboardButton.cs @@ -6,7 +6,8 @@ namespace Telegram.Bot.Types.ReplyMarkups; public interface IKeyboardButton { /// - /// Text of the button. If none of the optional fields are used, it will be sent as a message when the button is pressed + /// Text of the button. If none of the optional fields are used, + /// it will be sent as a message when the button is pressed /// - string Text { get; set; } -} \ No newline at end of file + string Text { get; } +} diff --git a/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardButton.cs b/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardButton.cs index ca7bfe755..1ec7a231e 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardButton.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardButton.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types.ReplyMarkups; /// @@ -8,11 +10,12 @@ public class InlineKeyboardButton : IKeyboardButton { /// [JsonProperty(Required = Required.Always)] - public string Text { get; set; } + public required string Text { get; init; } /// - /// Optional. HTTP or tg:// URL to be opened when the button is pressed. Links tg://user?id=<user_id> - /// can be used to mention a user by their ID without using a username, if this is allowed by their privacy settings. + /// Optional. HTTP or tg:// URL to be opened when the button is pressed. + /// Links tg://user?id=<user_id> can be used to mention a user by their ID without using a username, + /// if this is allowed by their privacy settings. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public string? Url { get; set; } @@ -82,7 +85,8 @@ public class InlineKeyboardButton : IKeyboardButton public CallbackGame? CallbackGame { get; set; } /// - /// Optional. Specify , to send a Pay button. + /// Optional. Specify , to send a + /// Pay button. /// /// /// NOTE: This type of button must always be the first button in the first row. @@ -90,11 +94,18 @@ public class InlineKeyboardButton : IKeyboardButton [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? Pay { get; set; } + /// + /// Instantiates new Inline Keyboard object + /// + public InlineKeyboardButton() + { } + /// /// Instantiates new Inline Keyboard object /// /// Label text on the button [JsonConstructor] + [SetsRequiredMembers] public InlineKeyboardButton(string text) { Text = text; @@ -178,7 +189,10 @@ public static InlineKeyboardButton WithSwitchInlineQueryCurrentChat(string text, /// with an optional default inline query. /// /// - public static InlineKeyboardButton WithSwitchInlineQueryChosenChat(string text, SwitchInlineQueryChosenChat switchInlineQueryChosenChat) => + public static InlineKeyboardButton WithSwitchInlineQueryChosenChat( + string text, + SwitchInlineQueryChosenChat switchInlineQueryChosenChat + ) => new(text) { SwitchInlineQueryChosenChat = switchInlineQueryChosenChat }; /// diff --git a/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardMarkup.cs b/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardMarkup.cs index 660d81caa..82edd77ac 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardMarkup.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/InlineKeyboardMarkup.cs @@ -18,12 +18,13 @@ public class InlineKeyboardMarkup : IReplyMarkup /// . /// [JsonProperty(Required = Required.Always)] - public IEnumerable> InlineKeyboard { get; } + public required IEnumerable> InlineKeyboard { get; init; } /// /// Initializes a new instance of the class with only one keyboard button /// /// Keyboard button + [SetsRequiredMembers] public InlineKeyboardMarkup(InlineKeyboardButton inlineKeyboardButton) : this(new[] { inlineKeyboardButton }) { } @@ -32,6 +33,7 @@ public InlineKeyboardMarkup(InlineKeyboardButton inlineKeyboardButton) /// Initializes a new instance of the class with a one-row keyboard /// /// The inline keyboard row + [SetsRequiredMembers] public InlineKeyboardMarkup(IEnumerable inlineKeyboardRow) : this(new[] { inlineKeyboardRow }) { } @@ -41,6 +43,7 @@ public InlineKeyboardMarkup(IEnumerable inlineKeyboardRow) /// /// The inline keyboard. [JsonConstructor] + [SetsRequiredMembers] public InlineKeyboardMarkup(IEnumerable> inlineKeyboard) => InlineKeyboard = inlineKeyboard; diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs index b56deff52..4b43751ba 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButton.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types.ReplyMarkups; /// @@ -11,7 +13,7 @@ public class KeyboardButton : IKeyboardButton { /// [JsonProperty(Required = Required.Always)] - public string Text { get; set; } + public required string Text { get; init; } /// /// Optional. If specified, pressing the button will open a list of suitable users. Identifiers of selected users @@ -60,6 +62,7 @@ public class KeyboardButton : IKeyboardButton /// /// Label text on the button [JsonConstructor] + [SetsRequiredMembers] public KeyboardButton(string text) => Text = text; /// diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonPollType.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonPollType.cs index b66a1cb0b..7ea6579ed 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonPollType.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonPollType.cs @@ -1,13 +1,15 @@ namespace Telegram.Bot.Types.ReplyMarkups; /// -/// This object represents type of a poll, which is allowed to be created and sent when the corresponding button is pressed. +/// This object represents type of a poll, which is allowed to be created +/// and sent when the corresponding button is pressed. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class KeyboardButtonPollType { /// - /// Optional. If quiz is passed, the user will be allowed to create only polls in the quiz mode. If regular is passed, only regular polls will be allowed. Otherwise, the user will be allowed to create a poll of any type. + /// Optional. If quiz is passed, the user will be allowed to create only polls in the quiz mode. If regular is + /// passed, only regular polls will be allowed. Otherwise, the user will be allowed to create a poll of any type. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public string? Type { get; set; } diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs index 5d13715fe..eaec4b34c 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestChat.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types.ReplyMarkups; /// @@ -12,13 +14,14 @@ public class KeyboardButtonRequestChat /// Must be unique within the message /// [JsonProperty(Required = Required.Always)] - public int RequestId { get; } + public required int RequestId { get; init; } /// - /// Pass to request a channel chat, pass to request a group or a supergroup chat. + /// Pass to request a channel chat, pass + /// to request a group or a supergroup chat. /// [JsonProperty(Required = Required.Always)] - public bool ChatIsChannel { get; } + public required bool ChatIsChannel { get; init; } /// /// Optional. Pass to request a forum supergroup, pass to @@ -72,11 +75,19 @@ public class KeyboardButtonRequestChat /// Must be unique within the message /// /// - /// Pass to request a channel chat, pass to request a group or a supergroup chat. + /// Pass to request a channel chat, pass + /// to request a group or a supergroup chat. /// + [SetsRequiredMembers] public KeyboardButtonRequestChat(int requestId, bool chatIsChannel) { RequestId = requestId; ChatIsChannel = chatIsChannel; } + + /// + /// Initializes a new instance of the class + /// + public KeyboardButtonRequestChat() + { } } diff --git a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs index ac03ca0d4..aae6ed7bd 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/KeyboardButtonRequestUsers.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types.ReplyMarkups; /// @@ -12,7 +14,7 @@ public class KeyboardButtonRequestUsers /// Must be unique within the message /// [JsonProperty(Required = Required.Always)] - public int RequestId { get; } + public required int RequestId { get; init; } /// /// Optional. Pass to request bots, pass to request regular users. @@ -41,8 +43,12 @@ public class KeyboardButtonRequestUsers /// Signed 32-bit identifier of the request that will be received back in the object. /// Must be unique within the message /// + [SetsRequiredMembers] public KeyboardButtonRequestUsers(int requestId) - { - RequestId = requestId; - } + => RequestId = requestId; + + /// + /// Initializes a new instance of the class + /// + public KeyboardButtonRequestUsers() {} } diff --git a/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardMarkup.cs b/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardMarkup.cs index 554f54b04..cfa85f53b 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardMarkup.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardMarkup.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Telegram.Bot.Types.ReplyMarkups; @@ -13,7 +14,7 @@ public class ReplyKeyboardMarkup : ReplyMarkupBase /// Array of button rows, each represented by an Array of KeyboardButton objects /// [JsonProperty(Required = Required.Always)] - public IEnumerable> Keyboard { get; set; } + public required IEnumerable> Keyboard { get; init; } /// /// Optional. Requests clients to always show the keyboard when the regular keyboard is hidden. Defaults to @@ -23,13 +24,17 @@ public class ReplyKeyboardMarkup : ReplyMarkupBase public bool? IsPersistent { get; set; } /// - /// Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always of the same height as the app's standard keyboard. + /// Optional. Requests clients to resize the keyboard vertically for optimal fit (e.g., make the keyboard smaller + /// if there are just two rows of buttons). Defaults to false, in which case the custom keyboard is always + /// of the same height as the app's standard keyboard. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? ResizeKeyboard { get; set; } /// - /// Optional. Requests clients to hide the keyboard as soon as it's been used. The keyboard will still be available, but clients will automatically display the usual letter-keyboard in the chat – the user can press a special button in the input field to see the custom keyboard again. Defaults to false. + /// Optional. Requests clients to hide the keyboard as soon as it's been used. The keyboard will still + /// be available, but clients will automatically display the usual letter-keyboard in the chat – the user can + /// press a special button in the input field to see the custom keyboard again. Defaults to false. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? OneTimeKeyboard { get; set; } @@ -40,32 +45,38 @@ public class ReplyKeyboardMarkup : ReplyMarkupBase [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public string? InputFieldPlaceholder { get; set; } + /// + /// Initializes a new instance of + /// + public ReplyKeyboardMarkup() + { } + /// /// Initializes a new instance of with one button /// /// Button on keyboard + [SetsRequiredMembers] public ReplyKeyboardMarkup(KeyboardButton button) - : this(new[] { button }) - { - } + : this([button]) + { } /// /// Initializes a new instance of /// /// The keyboard row. + [SetsRequiredMembers] public ReplyKeyboardMarkup(IEnumerable keyboardRow) - : this(new[] { keyboardRow }) + : this([keyboardRow]) { } /// /// Initializes a new instance of the class. /// /// The keyboard. + [SetsRequiredMembers] [JsonConstructor] public ReplyKeyboardMarkup(IEnumerable> keyboard) - { - Keyboard = keyboard; - } + => Keyboard = keyboard; /// /// Generates a reply keyboard markup with one button diff --git a/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardRemove.cs b/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardRemove.cs index 5d65082f1..736a2b8c1 100644 --- a/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardRemove.cs +++ b/src/Telegram.Bot/Types/ReplyMarkups/ReplyKeyboardRemove.cs @@ -1,13 +1,18 @@ namespace Telegram.Bot.Types.ReplyMarkups; /// -/// Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent by a bot. An exception is made for one-time keyboards that are hidden immediately after the user presses a button (see ). +/// Upon receiving a message with this object, Telegram clients will remove the current custom keyboard and display +/// the default letter-keyboard. By default, custom keyboards are displayed until a new keyboard is sent by a bot. +/// An exception is made for one-time keyboards that are hidden immediately after the user presses a button +/// (see ). /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class ReplyKeyboardRemove : ReplyMarkupBase { /// - /// Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to hide the keyboard from sight but keep it accessible, use '' in ) + /// Requests clients to remove the custom keyboard (user will not be able to summon this keyboard; if you want to + /// hide the keyboard from sight but keep it accessible, use '' + /// in ) /// [JsonProperty(Required = Required.Always)] public bool RemoveKeyboard => true; diff --git a/src/Telegram.Bot/Types/WebAppInfo.cs b/src/Telegram.Bot/Types/WebAppInfo.cs index 766a4bc92..d8750f555 100644 --- a/src/Telegram.Bot/Types/WebAppInfo.cs +++ b/src/Telegram.Bot/Types/WebAppInfo.cs @@ -1,3 +1,5 @@ +using System.Diagnostics.CodeAnalysis; + namespace Telegram.Bot.Types; /// @@ -11,7 +13,7 @@ public class WebAppInfo /// Initializing Web Apps /// [JsonProperty(Required = Required.Always)] - public string Url { get; } + public required string Url { get; init; } /// /// Initializes a new instance of the class with url @@ -20,8 +22,13 @@ public class WebAppInfo /// An HTTPS URL of a Web App to be opened with additional data as specified in /// Initializing Web Apps /// + [SetsRequiredMembers] public WebAppInfo(string url) - { - Url = url; - } + => Url = url; + + /// + /// Initializes a new instance of the class + /// + public WebAppInfo() + {} } diff --git a/test/Telegram.Bot.Tests.Integ/Framework/RetryTelegramBotClient.cs b/test/Telegram.Bot.Tests.Integ/Framework/RetryTelegramBotClient.cs index e0197e156..5bdae8b08 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/RetryTelegramBotClient.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/RetryTelegramBotClient.cs @@ -10,45 +10,30 @@ namespace Telegram.Bot.Tests.Integ.Framework; -internal class TestClientOptions : TelegramBotClientOptions +internal class TestClientOptions( + string token, + string? baseUrl, + bool useTestEnvironment, + int retryCount, + TimeSpan defaultTimeout) + : TelegramBotClientOptions(token, baseUrl, useTestEnvironment) { - public int RetryCount { get; } - public TimeSpan DefaultTimeout { get; } - - public TestClientOptions( - string token, - string? baseUrl, - bool useTestEnvironment, - int retryCount, - TimeSpan defaultTimeout) - : base(token, baseUrl, useTestEnvironment) - { - RetryCount = retryCount; - DefaultTimeout = defaultTimeout; - } + public int RetryCount { get; } = retryCount; + public TimeSpan DefaultTimeout { get; } = defaultTimeout; }; -internal class RetryTelegramBotClient : TelegramBotClient +internal class RetryTelegramBotClient( + IMessageSink diagnosticMessageSink, + TestClientOptions options) + : TelegramBotClient(options) { - readonly IMessageSink _diagnosticMessageSink; - readonly TestClientOptions _options; - - public RetryTelegramBotClient( - IMessageSink diagnosticMessageSink, - TestClientOptions options) - : base(options) - { - _diagnosticMessageSink = diagnosticMessageSink; - _options = options; - } - public override async Task MakeRequestAsync( IRequest request, CancellationToken cancellationToken = default) { ApiRequestException apiRequestException = default!; - for (var i = 0; i < _options.RetryCount; i++) + for (var i = 0; i < options.RetryCount; i++) { try { @@ -59,11 +44,11 @@ public override async Task MakeRequestAsync( apiRequestException = e; var timeout = e.Parameters?.RetryAfter is null - ? _options.DefaultTimeout + ? options.DefaultTimeout : TimeSpan.FromSeconds(e.Parameters.RetryAfter.Value); var message = $"Retry attempt {i + 1}. Waiting for {timeout} seconds before retrying."; - _diagnosticMessageSink.OnMessage(new DiagnosticMessage(message)); + diagnosticMessageSink.OnMessage(new DiagnosticMessage(message)); await Task.Delay(timeout, cancellationToken); } } diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs index 9ac362949..e396a6ddf 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs @@ -42,10 +42,11 @@ await BotClient.AnswerInlineQueryAsync( inlineQueryId: queryUpdate.InlineQuery!.Id, results: new InlineQueryResult[] { - new InlineQueryResultGame( - id: resultId, - gameShortName: _classFixture.GameShortName - ) + new InlineQueryResultGame + { + Id = resultId, + GameShortName = _classFixture.GameShortName, + } }, cacheTime: 0 ); @@ -116,4 +117,4 @@ await BotClient.AnswerCallbackQueryAsync( url: "https://tbot.xyz/lumber/" ); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs index d766aa5f2..18afa6074 100644 --- a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs @@ -42,15 +42,15 @@ await _fixture.SendTestInstructionsAsync( // Prepare results of the query InlineQueryResult[] results = - { - new InlineQueryResultArticle( - id: "article:bot-api", - title: "Telegram Bot API", - inputMessageContent: new InputTextMessageContent("https://core.telegram.org/bots/api")) + [ + new InlineQueryResultArticle { + Id = "article:bot-api", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { MessageText = "https://core.telegram.org/bots/api" }, Description = "The Bot API is an HTTP-based interface created for developers", - }, - }; + } + ]; // Answer the query await BotClient.AnswerInlineQueryAsync( @@ -87,15 +87,15 @@ await _fixture.SendTestInstructionsAsync( Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); InlineQueryResult[] results = - { - new InlineQueryResultArticle( - id: "article:bot-api", - title: "Telegram Bot API", - inputMessageContent: new InputTextMessageContent("https://core.telegram.org/bots/api")) + [ + new InlineQueryResultArticle { + Id = "article:bot-api", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { MessageText = "https://core.telegram.org/bots/api" }, Description = "The Bot API is an HTTP-based interface created for developers", - }, - }; + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -105,7 +105,7 @@ await BotClient.AnswerInlineQueryAsync( Update messageUpdate = await _fixture.UpdateReceiver.GetUpdateAsync( predicate: update => update.Message!.ViaBot is not null, - updateTypes: new[] { UpdateType.Message } + updateTypes: [UpdateType.Message] ); Assert.NotNull(messageUpdate.Message); @@ -127,12 +127,15 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "contact:john-doe"; InlineQueryResult[] results = - { - new InlineQueryResultContact(id: resultId, phoneNumber: "+1234567", firstName: "John") + [ + new InlineQueryResultContact { + Id = resultId, + PhoneNumber = "+1234567", + FirstName = "John", LastName = "Doe" } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -165,13 +168,15 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "location:hobitton"; InlineQueryResult[] results = - { - new InlineQueryResultLocation( - id: resultId, - latitude: -37.8721897f, - longitude: 175.6810213f, - title: "Hobbiton Movie Set") - }; + [ + new InlineQueryResultLocation + { + Id = resultId, + Latitude = -37.8721897f, + Longitude = 175.6810213f, + Title = "Hobbiton Movie Set" + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -204,14 +209,16 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "venue:hobbiton"; InlineQueryResult[] results = - { - new InlineQueryResultVenue( - id: resultId, - latitude: -37.8721897f, - longitude: 175.6810213f, - title: "Hobbiton Movie Set", - address: "501 Buckland Rd, Hinuera, Matamata 3472, New Zealand") - }; + [ + new InlineQueryResultVenue + { + Id = resultId, + Latitude = -37.8721897f, + Longitude = 175.6810213f, + Title = "Hobbiton Movie Set", + Address = "501 Buckland Rd, Hinuera, Matamata 3472, New Zealand", + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -246,12 +253,15 @@ await _fixture.SendTestInstructionsAsync( const string url = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg"; const string caption = "Rainbow Girl"; InlineQueryResult[] results = - { - new InlineQueryResultPhoto(id: resultId, photoUrl: url, thumbnailUrl: url) + [ + new InlineQueryResultPhoto { + Id = resultId, + PhotoUrl = url, + ThumbnailUrl = url, Caption = caption } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -292,14 +302,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Photo() const string resultId = "photo:apes"; const string caption = "Apes smoking shisha"; InlineQueryResult[] results = - { - new InlineQueryResultCachedPhoto( - id: resultId, - photoFileId: photoMessage.Photo!.First().FileId) + [ + new InlineQueryResultCachedPhoto { + Id = resultId, + PhotoFileId = photoMessage.Photo!.First().FileId, Caption = caption } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -333,16 +343,17 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "sunset_video"; InlineQueryResult[] results = - { - new InlineQueryResultVideo( - id: resultId, - videoUrl: "https://pixabay.com/en/videos/download/video-10737_medium.mp4", - thumbnailUrl: "https://i.vimeocdn.com/video/646283246_640x360.jpg", - title: "Sunset Landscape") + [ + new InlineQueryResultVideo { + Id = resultId, + VideoUrl = "https://pixabay.com/en/videos/download/video-10737_medium.mp4", + ThumbnailUrl = "https://i.vimeocdn.com/video/646283246_640x360.jpg", + MimeType = "video/mp4", + Title = "Sunset Landscape", Description = "A beautiful scene" } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -377,19 +388,21 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "youtube_video"; InlineQueryResult[] results = - { - new InlineQueryResultVideo( - id: resultId, - videoUrl: "https://www.youtube.com/watch?v=1S0CTtY8Qa0", - thumbnailUrl: "https://www.youtube.com/watch?v=1S0CTtY8Qa0", - title: "Rocket Launch", - inputMessageContent: - new InputTextMessageContent("[Rocket Launch](https://www.youtube.com/watch?v=1S0CTtY8Qa0)") + [ + new InlineQueryResultVideo + { + Id = resultId, + VideoUrl = "https://www.youtube.com/watch?v=1S0CTtY8Qa0", + ThumbnailUrl = "https://www.youtube.com/watch?v=1S0CTtY8Qa0", + MimeType = "video/mp4", + Title = "Rocket Launch", + InputMessageContent = new InputTextMessageContent { + MessageText = "[Rocket Launch](https://www.youtube.com/watch?v=1S0CTtY8Qa0)", ParseMode = ParseMode.Markdown } - ) - }; + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -425,15 +438,15 @@ public async Task Should_Answer_Inline_Query_With_Cached_Video() const string resultId = "fireworks_video"; InlineQueryResult[] results = - { - new InlineQueryResultCachedVideo( - id: resultId, - videoFileId: videoMessage.Video!.FileId, - title: "New Year's Eve Fireworks") + [ + new InlineQueryResultCachedVideo { + Id = resultId, + VideoFileId = videoMessage.Video!.FileId, + Title = "New Year's Eve Fireworks", Description = "2017 Fireworks in Germany" } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -466,17 +479,16 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "audio_result"; InlineQueryResult[] results = - { - new InlineQueryResultAudio( - id: resultId, - audioUrl: - "https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3", - title: "Test ogg mp3") + [ + new InlineQueryResultAudio { + Id = resultId, + AudioUrl = "https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3", + Title = "Test ogg mp3", Performer = "Shishirdasika", AudioDuration = 25 } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -518,14 +530,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Audio() const string resultId = "audio_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedAudio( - id: resultId, - audioFileId: audioMessage.Audio!.FileId) + [ + new InlineQueryResultCachedAudio { + Id = resultId, + AudioFileId = audioMessage.Audio!.FileId, Caption = "Jackson F. Smith - Cantina Rag" } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -558,16 +570,16 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "voice_result"; InlineQueryResult[] results = - { - new InlineQueryResultVoice( - id: resultId, - voiceUrl: "http://www.vorbis.com/music/Hydrate-Kenny_Beltrey.ogg", - title: "Hydrate - Kenny Beltrey") + [ + new InlineQueryResultVoice { + Id = resultId, + VoiceUrl = "http://www.vorbis.com/music/Hydrate-Kenny_Beltrey.ogg", + Title = "Hydrate - Kenny Beltrey", Caption = "Hydrate - Kenny Beltrey", VoiceDuration = 265 } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -607,13 +619,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Voice() const string resultId = "voice_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedVoice( - id: resultId, - fileId: voiceMessage.Voice!.FileId, - title: "Test Voice" - ) - }; + [ + new InlineQueryResultCachedVoice + { + Id = resultId, + VoiceFileId = voiceMessage.Voice!.FileId, + Title = "Test Voice", + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -646,17 +659,17 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "document_result"; InlineQueryResult[] results = - { - new InlineQueryResultDocument( - id: resultId, - documentUrl: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", - title: "Dummy PDF File", - mimeType: "application/pdf") + [ + new InlineQueryResultDocument { + Id = resultId, + DocumentUrl = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", + Title = "Dummy PDF File", + MimeType = "application/pdf", Caption = "Dummy PDF File", Description = "Dummy PDF File for testing", } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -695,16 +708,16 @@ public async Task Should_Answer_Inline_Query_With_Cached_Document() const string resultId = "document_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedDocument( - id: resultId, - documentFileId: documentMessage.Document!.FileId, - title: "Test Document") + [ + new InlineQueryResultCachedDocument { + Id = resultId, + DocumentFileId = documentMessage.Document!.FileId, + Title = "Test Document", Caption = "The Tragedy of Hamlet, Prince of Denmark", Description = "Sample PDF Document", } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -737,12 +750,12 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "gif_result"; InlineQueryResult[] results = - { - new InlineQueryResultGif( - id: resultId, - gifUrl: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif", - thumbnailUrl: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif") + [ + new InlineQueryResultGif { + Id = resultId, + GifUrl = "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif", + ThumbnailUrl = "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif", Caption = "Rotating Earth", GifDuration = 4, GifHeight = 400, @@ -750,7 +763,7 @@ await _fixture.SendTestInstructionsAsync( Title = "Rotating Earth", ThumbnailMimeType = "image/gif", } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -784,14 +797,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Gif() const string resultId = "gif_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedGif( - id: resultId, - gifFileId: gifMessage.Document!.FileId) + [ + new InlineQueryResultCachedGif { + Id = resultId, + GifFileId = gifMessage.Document!.FileId, Caption = "Rotating Earth", } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -824,15 +837,15 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "mpeg4_gif_result"; InlineQueryResult[] results = - { - new InlineQueryResultMpeg4Gif( - id: resultId, - mpeg4Url: "https://pixabay.com/en/videos/download/video-10737_medium.mp4", - thumbnailUrl: "https://i.vimeocdn.com/video/646283246_640x360.jpg") + [ + new InlineQueryResultMpeg4Gif { + Id = resultId, + Mpeg4Url = "https://pixabay.com/en/videos/download/video-10737_medium.mp4", + ThumbnailUrl = "https://i.vimeocdn.com/video/646283246_640x360.jpg", Caption = "A beautiful scene", - }, - }; + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -866,14 +879,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Mpeg4Gif() const string resultId = "mpeg4_gif_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedMpeg4Gif( - id: resultId, - mpeg4FileId: gifMessage.Document!.FileId) + [ + new InlineQueryResultCachedMpeg4Gif { + Id = resultId, + Mpeg4FileId = gifMessage.Document!.FileId, Caption = "Rotating Earth", } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -909,9 +922,13 @@ await _fixture.SendTestInstructionsAsync( const string resultId = "sticker_result"; InlineQueryResult[] results = - { - new InlineQueryResultCachedSticker(id: resultId, stickerFileId: stickerSet.Stickers[0].FileId) - }; + [ + new InlineQueryResultCachedSticker + { + Id = resultId, + StickerFileId = stickerSet.Stickers[0].FileId, + } + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -946,13 +963,16 @@ await _fixture.SendTestInstructionsAsync( const string url = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg"; const string photoCaption = "Rainbow Girl"; InlineQueryResult[] results = - { - new InlineQueryResultPhoto(id: resultId, photoUrl: url, thumbnailUrl: url) + [ + new InlineQueryResultPhoto { + Id = resultId, + PhotoUrl = url, + ThumbnailUrl = url, Caption = $"*{photoCaption}*", ParseMode = ParseMode.Markdown } - }; + ]; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, @@ -987,15 +1007,15 @@ await _fixture.SendTestInstructionsAsync( Update queryUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); InlineQueryResult[] results = - { - new InlineQueryResultArticle( - id: "article:bot-api", - title: "Telegram Bot API", - inputMessageContent: new InputTextMessageContent("https://core.telegram.org/bots/api")) + [ + new InlineQueryResultArticle { + Id = "article:bot-api", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { MessageText = "https://core.telegram.org/bots/api"}, Description = "The Bot API is an HTTP-based interface created for developers", - }, - }; + } + ]; await Task.Delay(10_000); diff --git a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs index dc4166aa6..48213b702 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs +++ b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs @@ -38,23 +38,21 @@ await _fixture.SendTestInstructionsAsync( Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); string callbackQueryData = $"edit-location{new Random().Next(1_000)}"; - Location newYork = new Location {Latitude = 40.7128f, Longitude = -74.0060f}; + Location newYork = new() { Latitude = 40.7128f, Longitude = -74.0060f }; await BotClient.AnswerInlineQueryAsync( inlineQueryId: iqUpdate.InlineQuery!.Id, cacheTime: 0, results: new[] { - new InlineQueryResultLocation( - id: "live-location", - latitude: newYork.Latitude, - longitude: newYork.Longitude, - title: "Live Locations Test") + new InlineQueryResultLocation { + Id = "live-location", + Latitude = newYork.Latitude, + Longitude = newYork.Longitude, + Title = "Live Locations Test", LivePeriod = 60, - ReplyMarkup = InlineKeyboardButton.WithCallbackData( - "Start live locations", callbackQueryData - ) + ReplyMarkup = InlineKeyboardButton.WithCallbackData("Start live locations", callbackQueryData) } } ); @@ -71,7 +69,7 @@ public async Task Should_Edit_Inline_Message_Live_Location() Update cqUpdate = await _fixture.UpdateReceiver .GetCallbackQueryUpdateAsync(data: _classFixture.CallbackQueryData); - Location beijing = new Location {Latitude = 39.9042f, Longitude = 116.4074f}; + Location beijing = new() { Latitude = 39.9042f, Longitude = 116.4074f }; await BotClient.EditMessageLiveLocationAsync( inlineMessageId: cqUpdate.CallbackQuery!.InlineMessageId!, @@ -98,4 +96,4 @@ public class Fixture public string CallbackQueryData { get; set; } } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs b/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs index 2ff54b06d..d014cc4a0 100644 --- a/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs +++ b/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs @@ -200,15 +200,15 @@ public SendInvoiceRequest BuildInvoiceRequest() if (string.IsNullOrWhiteSpace(_currency)) throw new InvalidOperationException("Currency isn't set"); if (string.IsNullOrWhiteSpace(_payload)) throw new InvalidOperationException("Payload isn't set"); - return new( - chatId: _chatId.Value, - title: _product.Title, - description: _product.Description, - payload: _payload, - providerToken: _paymentsProviderToken, - currency: _currency, - prices: _product.ProductPrices) + return new() { + ChatId = _chatId.Value, + Title = _product.Title, + Description = _product.Description, + Payload = _payload, + ProviderToken = _paymentsProviderToken, + Currency = _currency, + Prices = _product.ProductPrices, PhotoUrl = _product.PhotoUrl, PhotoWidth = _product.PhotoWidth, PhotoHeight = _product.PhotoHeight, diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs index d90a609fd..c33c0d231 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs @@ -1,3 +1,4 @@ +using System; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -37,13 +38,15 @@ public async Task Should_Upload_2_Photos_Album() { IAlbumInputMedia[] inputMedia = [ - new InputMediaPhoto(new InputFileStream(stream1, "logo.png")) + new InputMediaPhoto { - Caption = "Logo" + Media = InputFile.FromStream(stream1, "logo.png"), + Caption = "Logo", }, - new InputMediaPhoto(new InputFileStream(stream2, "bot.gif")) + new InputMediaPhoto { - Caption = "Bot" + Media = InputFile.FromStream(stream2, "bot.gif"), + Caption = "Bot", }, ]; @@ -80,9 +83,9 @@ public async Task Should_Send_3_Photos_Album_Using_FileId() chatId: _fixture.SupergroupChat.Id, media: new IAlbumInputMedia[] { - new InputMediaPhoto(new InputFileId(fileIds[0])), - new InputMediaPhoto(new InputFileId(fileIds[1])), - new InputMediaPhoto(new InputFileId(fileIds[0])), + new InputMediaPhoto { Media = new InputFileId(fileIds[0])}, + new InputMediaPhoto { Media = new InputFileId(fileIds[1])}, + new InputMediaPhoto { Media = new InputFileId(fileIds[0])}, } ); @@ -101,8 +104,8 @@ public async Task Should_Send_Photo_Album_Using_Url() chatId: _fixture.SupergroupChat.Id, media: new IAlbumInputMedia[] { - new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/06/20/19/22/fuchs-2424369_640.jpg")), - new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")), + new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/06/20/19/22/fuchs-2424369_640.jpg")}, + new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")}, }, replyParameters: new() { MessageId = replyToMessageId } ); @@ -130,19 +133,22 @@ public async Task Should_Upload_2_Videos_Album() { IAlbumInputMedia[] inputMedia = [ - new InputMediaVideo(new InputFileStream(stream0, "GoldenRatio.mp4")) + new InputMediaVideo { + Media = InputFile.FromStream(stream0, "GoldenRatio.mp4"), Caption = "Golden Ratio", Height = 240, Width = 240, Duration = 28, }, - new InputMediaVideo(new InputFileStream(stream1, "MoonLanding.mp4")) + new InputMediaVideo { + Media = InputFile.FromStream(stream1, "MoonLanding.mp4"), Caption = "Moon Landing" }, - new InputMediaPhoto(new InputFileStream(stream2, "bot.gif")) + new InputMediaPhoto { + Media = InputFile.FromStream(stream2, "bot.gif"), Caption = "Bot" }, ]; @@ -186,13 +192,15 @@ public async Task Should_Upload_2_Photos_Album_With_Markdown_Encoded_Captions() IAlbumInputMedia[] inputMedia = [ - new InputMediaPhoto(new InputFileStream(stream1, "logo.png")) + new InputMediaPhoto { + Media = InputFile.FromStream(stream1, "logo.png"), Caption = "*Logo*", ParseMode = ParseMode.Markdown }, - new InputMediaPhoto(new InputFileStream(stream2, "bot.gif")) + new InputMediaPhoto { + Media = InputFile.FromStream(stream2, "bot.gif"), Caption = "_Bot_", ParseMode = ParseMode.Markdown }, @@ -229,12 +237,16 @@ public async Task Should_Video_With_Thumbnail_In_Album() IAlbumInputMedia[] inputMedia = [ - new InputMediaVideo(new InputFileStream(stream1, "GoldenRatio.mp4")) + new InputMediaVideo { + Media = InputFile.FromStream(stream1, "GoldenRatio.mp4"), Thumbnail = new InputFileStream(stream2, "thumbnail.jpg"), SupportsStreaming = true, }, - new InputMediaPhoto(new InputFileUrl("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")), + new InputMediaPhoto + { + Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg"), + }, ]; Message[] messages = await BotClient.SendMediaGroupAsync( diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs index 10bee59bd..c941f233b 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs @@ -36,7 +36,7 @@ public async Task Should_Upload_Static_Sticker_File() File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, - sticker: new InputFileStream(stream), + sticker: new(stream), stickerFormat: StickerFormat.Static ); @@ -54,7 +54,7 @@ public async Task Should_Upload_Animated_Sticker_File() File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, - sticker: new InputFileStream(stream), + sticker: new(stream), stickerFormat: StickerFormat.Animated ); @@ -72,7 +72,7 @@ public async Task Should_Upload_Video_Sticker_File() File file = await BotClient.UploadStickerFileAsync( userId: _stickersTestsFixture.OwnerUserId, - sticker: new InputFileStream(stream), + sticker: new(stream), stickerFormat: StickerFormat.Video ); @@ -95,11 +95,11 @@ public async Task Should_Create_New_Static_Sticker_Set() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis ), - new InputSticker( + new( sticker: new InputFileStream(stream, "Static2.webp"), emojiList: _stickersTestsFixture.SecondEmojis ), @@ -135,11 +135,11 @@ public async Task Should_Create_New_Animated_Sticker_Set() ); List inputStickers = [ - new InputSticker( + new( sticker: new InputFileId(_stickersTestsFixture.TestUploadedAnimatedStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis ), - new InputSticker( + new( sticker: new InputFileStream(stream, "Animated2.webp"), emojiList: _stickersTestsFixture.SecondEmojis ), @@ -175,11 +175,11 @@ public async Task Should_Create_New_Video_Sticker_Set() ); List inputStickers = [ - new InputSticker( + new( sticker: new InputFileId(_stickersTestsFixture.TestUploadedVideoStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis ), - new InputSticker( + new( sticker: new InputFileStream(stream, "Video2.webp"), emojiList: _stickersTestsFixture.SecondEmojis ), @@ -232,6 +232,7 @@ public async Task Should_Send_Static_Sticker() ); Assert.Equal(MessageType.Sticker, stickerMessage.Type); + Assert.NotNull(stickerMessage.Sticker); Assert.Equal(firstSticker.FileUniqueId, stickerMessage.Sticker.FileUniqueId); Assert.Equal(firstSticker.FileSize, stickerMessage.Sticker.FileSize); Assert.Equal(firstSticker.Type, stickerMessage.Sticker.Type); @@ -239,6 +240,8 @@ public async Task Should_Send_Static_Sticker() Assert.Equal(firstSticker.Height, stickerMessage.Sticker.Height); Assert.False(stickerMessage.Sticker.IsAnimated); Assert.False(stickerMessage.Sticker.IsVideo); + Assert.NotNull(firstSticker.Thumbnail); + Assert.NotNull(stickerMessage.Sticker.Thumbnail); Assert.Equal(firstSticker.Thumbnail.FileUniqueId, stickerMessage.Sticker.Thumbnail.FileUniqueId); Assert.Equal(firstSticker.Thumbnail.FileSize, stickerMessage.Sticker.Thumbnail.FileSize); Assert.Equal(firstSticker.Thumbnail.Width, stickerMessage.Sticker.Thumbnail.Width); @@ -273,6 +276,7 @@ public async Task Should_Send_Animated_Sticker() ); Assert.Equal(MessageType.Sticker, stickerMessage.Type); + Assert.NotNull(stickerMessage.Sticker); Assert.Equal(firstSticker.FileUniqueId, stickerMessage.Sticker.FileUniqueId); Assert.Equal(firstSticker.FileSize, stickerMessage.Sticker.FileSize); Assert.Equal(firstSticker.Type, stickerMessage.Sticker.Type); @@ -280,6 +284,8 @@ public async Task Should_Send_Animated_Sticker() Assert.Equal(firstSticker.Height, stickerMessage.Sticker.Height); Assert.True(stickerMessage.Sticker.IsAnimated); Assert.False(stickerMessage.Sticker.IsVideo); + Assert.NotNull(firstSticker.Thumbnail); + Assert.NotNull(stickerMessage.Sticker.Thumbnail); Assert.Equal(firstSticker.Thumbnail.FileUniqueId, stickerMessage.Sticker.Thumbnail.FileUniqueId); Assert.Equal(firstSticker.Thumbnail.FileSize, stickerMessage.Sticker.Thumbnail.FileSize); Assert.Equal(firstSticker.Thumbnail.Width, stickerMessage.Sticker.Thumbnail.Width); @@ -463,7 +469,7 @@ public async Task Should_Change_Sticker_Position_In_Set() Sticker thirdSticker = stickerSet.Stickers[2]; await BotClient.SetStickerPositionInSetAsync( - sticker: new InputFileId(thirdSticker.FileId), + sticker: new(thirdSticker.FileId), position: 0 ); @@ -492,7 +498,7 @@ public async Task Should_Delete_Sticker_From_Set() Sticker thirdSticker = stickerSet.Stickers[2]; await BotClient.DeleteStickerFromSetAsync( - sticker: new InputFileId(thirdSticker.FileId) + sticker: new(thirdSticker.FileId) ); await Task.Delay(1_000); @@ -522,7 +528,7 @@ public async Task Should_Set_First_Sticker_EmojiList() Assert.Equal(thirdEmojisString, firstSticker.Emoji); await BotClient.SetStickerEmojiListAsync( - sticker: new InputFileId(firstSticker.FileId), + sticker: new(firstSticker.FileId), emojiList: _stickersTestsFixture.FirstEmojis ); @@ -555,14 +561,14 @@ public async Task Should_Set_First_Sticker_Keywords() Sticker firstSticker = stickerSet.Stickers.First(); await BotClient.SetStickerKeywordsAsync( - sticker: new InputFileId(firstSticker.FileId), + sticker: new(firstSticker.FileId), keywords: keywords ); await Task.Delay(1_000); await BotClient.SetStickerKeywordsAsync( - sticker: new InputFileId(firstSticker.FileId), + sticker: new(firstSticker.FileId), keywords: null ); } @@ -627,7 +633,7 @@ public async Task Should_Throw_InvalidStickerSetNameException() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: _stickersTestsFixture.FirstEmojis ) @@ -656,7 +662,7 @@ public async Task Should_Throw_InvalidStickerEmojisException() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), emojiList: invalidEmojis ) @@ -687,7 +693,7 @@ public async Task Should_Throw_InvalidStickerDimensionsException() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileStream(stream, "logo.png"), emojiList: _stickersTestsFixture.FirstEmojis ) @@ -719,7 +725,7 @@ public async Task Should_Throw_InvalidFileSizeException() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileStream(stream, "apes.jpg"), emojiList: _stickersTestsFixture.FirstEmojis ) @@ -749,7 +755,7 @@ public async Task Should_Throw_StickerSetNameExistsException() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileStream(stream, "ruby.png"), emojiList: _stickersTestsFixture.FirstEmojis ) @@ -783,14 +789,14 @@ public async Task Should_Throw_StickerSetNotModifiedException() Sticker lastSticker = stickerSet.Stickers.Last(); await BotClient.DeleteStickerFromSetAsync( - sticker: new InputFileId(lastSticker.FileId) + sticker: new(lastSticker.FileId) ); await Task.Delay(TimeSpan.FromSeconds(10)); ApiRequestException exception = await Assert.ThrowsAsync(async () => await BotClient.DeleteStickerFromSetAsync( - sticker: new InputFileId(lastSticker.FileId) + sticker: new(lastSticker.FileId) ) ); @@ -855,7 +861,7 @@ public async Task Should_Create_New_Mask_Static_Sticker_Set() ); List inputStickers = [ - new InputSticker( + new( sticker: new InputFileStream(stream, "tux.png"), emojiList: _stickersTestsFixture.SecondEmojis) ]; @@ -893,7 +899,7 @@ public async Task Should_Add_Sticker_With_Mask_Position_To_Set() emojiList: _stickersTestsFixture.SecondEmojis ) { - MaskPosition = new MaskPosition + MaskPosition = new() { Point = MaskPositionPoint.Forehead, Scale = .8f @@ -941,7 +947,7 @@ public async Task Should_Set_Mask_Position_From_Last_Sticker() Sticker sticker = stickerSet.Stickers.First(); await BotClient.SetStickerMaskPositionAsync( - sticker: new InputFileId(sticker.FileId), + sticker: new(sticker.FileId), maskPosition: newMaskPosition ); @@ -993,7 +999,7 @@ public async Task Should_Create_New_Custom_Emoji_Static_Sticker_Set() List inputStickers = [ - new InputSticker( + new( sticker: new InputFileStream(stream, "Static1.png"), emojiList: _stickersTestsFixture.FirstEmojis) ]; diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs index 92dabe0c6..8c2c33775 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs @@ -36,11 +36,12 @@ await BotClient.AnswerInlineQueryAsync( inlineQueryId: queryUpdate.InlineQuery!.Id, results: new[] { - new InlineQueryResultArticle( - id: "article-to-delete", - title: "Telegram Bot API", - inputMessageContent: new InputTextMessageContent("https://www.telegram.org/") - ) + new InlineQueryResultArticle + { + Id = "article-to-delete", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { MessageText = "https://www.telegram.org/"}, + } }, cacheTime: 0 ); @@ -58,4 +59,4 @@ await BotClient.DeleteMessageAsync( messageId: messageUpdate.Message.MessageId ); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs index 6c9eb2cbf..4648b5884 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs @@ -50,16 +50,15 @@ await _fixture.SendTestInstructionsAsync( InlineQueryResult[] inlineQueryResults = { - new InlineQueryResultArticle( - id: "bot-api", - title: "Telegram Bot API", - inputMessageContent: - new InputTextMessageContent(messageText) + new InlineQueryResultArticle + { + Id = "bot-api", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { + MessageText = messageText, ParseMode = ParseMode.Html - } - ) - { + }, ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to modify text", data) } }; @@ -105,16 +104,18 @@ await _fixture.SendTestInstructionsAsync( InlineKeyboardButton.WithCallbackData("Click here to change this button", data) }); - InputMessageContent inputMessageContent = - new InputTextMessageContent("https://core.telegram.org/bots/api"); + InputMessageContent inputMessageContent = new InputTextMessageContent + { + MessageText = "https://core.telegram.org/bots/api" + }; InlineQueryResult[] inlineQueryResults = { - new InlineQueryResultArticle( - id: "bot-api", - title: "Telegram Bot API", - inputMessageContent: inputMessageContent) + new InlineQueryResultArticle { + Id = "bot-api", + Title = "Telegram Bot API", + InputMessageContent = inputMessageContent, Description = "The Bot API is an HTTP-based interface created for developers", ReplyMarkup = initialMarkup, }, @@ -160,11 +161,11 @@ await _fixture.SendTestInstructionsAsync( InlineQueryResult[] inlineQueryResults = { - new InlineQueryResultPhoto( - id: "photo1", - photoUrl: url, - thumbnailUrl: url) + new InlineQueryResultPhoto { + Id = "photo1", + PhotoUrl = url, + ThumbnailUrl = url, Caption = "Message caption will be updated shortly", ReplyMarkup = replyMarkup } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs index 4a6126be4..b14aa2582 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs @@ -40,11 +40,11 @@ await _fixture.SendTestInstructionsAsync( InlineQueryResult[] inlineQueryResults = { - new InlineQueryResultPhoto( - id: "photo:rainbow-girl", - photoUrl: "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg", - thumbnailUrl: "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg") + new InlineQueryResultPhoto { + Id = "photo:rainbow-girl", + PhotoUrl = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg", + ThumbnailUrl = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg", Caption = "Rainbow Girl", ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to edit"), } @@ -62,12 +62,12 @@ await _fixture.SendTestInstructionsAsync( // Change the photo for an audio. Note that, in the case of an inline message, the new media should be // either an URL or the file_id of a previously uploaded media. + InputFileUrl inputFileUrl = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3"); await BotClient.EditMessageMediaAsync( inlineMessageId: cqUpdate.CallbackQuery.InlineMessageId, - media: new InputMediaAudio(new InputFileUrl( - "https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/" + - "Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3")) + media: new InputMediaAudio { + Media = inputFileUrl, Caption = "**Audio** in `.mp3` format", ParseMode = ParseMode.Markdown, } @@ -101,12 +101,12 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() InlineQueryResult[] inlineQueryResults = { - new InlineQueryResultDocument( - id: "document:acrobat", - documentUrl: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", - title: "Dummy PDF File", - mimeType: "application/pdf") + new InlineQueryResultDocument { + Id = "document:acrobat", + DocumentUrl = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", + Title = "Dummy PDF File", + MimeType = "application/pdf", ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to edit"), } }; @@ -125,7 +125,7 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() // Also, animation thumbnail cannot be uploaded for an inline message. await BotClient.EditMessageMediaAsync( inlineMessageId: cqUpdate.CallbackQuery.InlineMessageId, - media: new InputMediaAnimation(new InputFileId(animationFileId)) + media: new InputMediaAnimation { Media = InputFile.FromFileId(animationFileId) } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs index 986f4ba9d..786bad267 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs @@ -46,8 +46,9 @@ public async Task Should_Edit_Message_Video() editedMessage = await BotClient.EditMessageMediaAsync( chatId: originalMessage.Chat, messageId: originalMessage.MessageId, - media: new InputMediaDocument(new InputFileStream(stream, "public-key.pem.txt")) + media: new InputMediaDocument { + Media = InputFile.FromStream(stream, "public-key.pem.txt"), Caption = "**Public** key in `.pem` format", ParseMode = ParseMode.Markdown, } @@ -90,8 +91,9 @@ public async Task Should_Edit_Message_Photo() Message editedMessage = await BotClient.EditMessageMediaAsync( chatId: originalMessage.Chat, messageId: originalMessage.MessageId, - media: new InputMediaAnimation(new InputFileId(gifMessage.Document.FileId)) + media: new InputMediaAnimation { + Media = InputFile.FromFileId(gifMessage.Document.FileId), Thumbnail = new InputFileStream(thumbStream, "thumb.jpg"), Duration = 4, Height = 320, From 0991ea369e40788e45c9f49c0ee6855efbf3ca74 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 08:52:22 +0400 Subject: [PATCH 74/90] Rename UnpinAllGeneralForumTopicMessages to UnpinAllGeneralForumTopicMessagesRequest --- CHANGELOG.md | 1 + ...ges.cs => UnpinAllGeneralForumTopicMessagesRequest.cs} | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) rename src/Telegram.Bot/Requests/Available methods/Manage Chat/{UnpinAllGeneralForumTopicMessages.cs => UnpinAllGeneralForumTopicMessagesRequest.cs} (79%) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc61bd8d6..b84496f9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ in the class `Update`. The bot must be an administrator in the chat to receive t ### Changed +- Class `UnpinAllGeneralForumTopicMessages` renamed to `UnpinAllGeneralForumTopicMessagesRequest` - Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods - `ITelegramBotClient.CopyMessageAsync`, - `ITelegramBotClient.SendMessageAsync`, diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs similarity index 79% rename from src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs rename to src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs index c78d4c004..7accadd59 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs @@ -10,7 +10,7 @@ namespace Telegram.Bot.Requests; /// Returns on success. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class UnpinAllGeneralForumTopicMessages : RequestBase, IChatTargetable +public class UnpinAllGeneralForumTopicMessagesRequest : RequestBase, IChatTargetable { /// [JsonProperty(Required = Required.Always)] @@ -21,8 +21,8 @@ public class UnpinAllGeneralForumTopicMessages : RequestBase, IChatTargeta /// /// Unique identifier for the target chat or username of the target supergroup [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] - public UnpinAllGeneralForumTopicMessages(ChatId chatId) + [Obsolete("Use parameterless constructor with required properties")] + public UnpinAllGeneralForumTopicMessagesRequest(ChatId chatId) : this() { ChatId = chatId; @@ -31,7 +31,7 @@ public UnpinAllGeneralForumTopicMessages(ChatId chatId) /// /// Initializes a new request /// - public UnpinAllGeneralForumTopicMessages() + public UnpinAllGeneralForumTopicMessagesRequest() : base("unpinAllGeneralForumTopicMessages") { } } From 71c7f960ae74a79f83867820acfa03237c606518 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 08:55:54 +0400 Subject: [PATCH 75/90] Add UnpinAllGeneralForumTopicMessagesRequest and made UnpinAllGeneralForumTopicMessages obsolete for naming consistency --- CHANGELOG.md | 4 +- .../UnpinAllGeneralForumTopicMessages.cs | 38 +++++++++++++++++++ ...npinAllGeneralForumTopicMessagesRequest.cs | 4 +- 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index b84496f9e..4e82656db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ### Added +- Class `UnpinAllGeneralForumTopicMessagesRequest` - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. - Enum `ReactionTypeKind` - The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. @@ -72,8 +73,7 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Fields `Chat` and `Id` to type `Story` ### Changed - -- Class `UnpinAllGeneralForumTopicMessages` renamed to `UnpinAllGeneralForumTopicMessagesRequest` +- Class `UnpinAllGeneralForumTopicMessages` marked as obsolete - Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods - `ITelegramBotClient.CopyMessageAsync`, - `ITelegramBotClient.SendMessageAsync`, diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs new file mode 100644 index 000000000..e95f50681 --- /dev/null +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessages.cs @@ -0,0 +1,38 @@ +using System.Diagnostics.CodeAnalysis; +using Telegram.Bot.Requests.Abstractions; + +// ReSharper disable once CheckNamespace +namespace Telegram.Bot.Requests; + +/// +/// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator in +/// the chat for this to work and must have the administrator +/// right in the supergroup. Returns on success. +/// +[JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] +[Obsolete("Use class UnpinAllGeneralForumTopicMessagesRequest")] +public class UnpinAllGeneralForumTopicMessages : RequestBase, IChatTargetable +{ + /// + [JsonProperty(Required = Required.Always)] + public required ChatId ChatId { get; init; } + + /// + /// Initializes a new request + /// + /// Unique identifier for the target chat or username of the target supergroup + [SetsRequiredMembers] + [Obsolete("Use parameterless constructor with required properties")] + public UnpinAllGeneralForumTopicMessages(ChatId chatId) + : this() + { + ChatId = chatId; + } + + /// + /// Initializes a new request + /// + public UnpinAllGeneralForumTopicMessages() + : base("unpinAllGeneralForumTopicMessages") + { } +} diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs index 7accadd59..4bd82407a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllGeneralForumTopicMessagesRequest.cs @@ -6,8 +6,8 @@ namespace Telegram.Bot.Requests; /// /// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator in -/// the chat for this to work and must have the administrator right in the supergroup. -/// Returns on success. +/// the chat for this to work and must have the administrator +/// right in the supergroup. Returns on success. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class UnpinAllGeneralForumTopicMessagesRequest : RequestBase, IChatTargetable From 68b3d6239328711f33454ab8912d973cf265f3aa Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 08:56:53 +0400 Subject: [PATCH 76/90] Add overloads that accept request classes instead of positional parameters --- ...BotClientExtensions.ApiMethods.Requests.cs | 2529 +++++++++++++++++ 1 file changed, 2529 insertions(+) create mode 100644 src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs new file mode 100644 index 000000000..a53fd831a --- /dev/null +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs @@ -0,0 +1,2529 @@ +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Telegram.Bot.Extensions; +using Telegram.Bot.Requests; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Types.Payments; +using Telegram.Bot.Types.ReplyMarkups; +using File = Telegram.Bot.Types.File; + +namespace Telegram.Bot; + +/// +/// Extension methods that map to requests from Bot API documentation +/// +public static partial class TelegramBotClientExtensions +{ + /// + /// Use this method to send answers to callback queries sent from + /// inline keyboards. The answer will be displayed + /// to the user as a notification at the top of the chat screen or as an alert + /// + /// + /// Alternatively, the user can be redirected to the specified Game URL.For this option to work, you must + /// first create a game for your bot via @BotFather and accept the terms. Otherwise, you may use + /// links like t.me/your_bot?start=XXXX that open your bot with a parameter + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerCallbackQueryAsync( + this ITelegramBotClient botClient, + AnswerCallbackQueryRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete the list of the bot’s commands for the given + /// and user language. After deletion, + /// higher level commands + /// will be shown to affected users + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteMyCommandsAsync( + this ITelegramBotClient botClient, + DeleteMyCommandsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current list of the bot’s commands for the given + /// and user language + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns Array of on success. If commands aren't set, an empty list is returned + /// + public static async Task GetMyCommandsAsync( + this ITelegramBotClient botClient, + GetMyCommandsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the list of the bot’s commands. + /// See for more details about bot commands + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMyCommandsAsync( + this ITelegramBotClient botClient, + SetMyCommandsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current bot description + /// for the given user language. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns on success. + /// + public static async Task GetMyDescriptionAsync( + this ITelegramBotClient botClient, + GetMyDescriptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the bot's description, which is shown in the chat + /// with the bot if the chat is empty. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMyDescriptionAsync( + this ITelegramBotClient botClient, + SetMyDescriptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get basic info about a file and prepare it for downloading. For the moment, bots can + /// download files of up to 20MB in size. The file can then be downloaded via the link + /// https://api.telegram.org/file/bot<token>/<file_path>, where <file_path> + /// is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. + /// When the link expires, a new one can be requested by calling + /// GetFileAsync again. + /// + /// + /// You can use or + /// methods to download the file + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, a object is returned. + public static async Task GetFileAsync( + this ITelegramBotClient botClient, + GetFileRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get basic info about a file download it. For the moment, bots can download files + /// of up to 20MB in size. + /// + /// An instance of + /// File identifier to get info about + /// Destination stream to write file to + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, a object is returned. + public static async Task GetInfoAndDownloadFileAsync( + this ITelegramBotClient botClient, + string fileId, + Stream destination, + CancellationToken cancellationToken = default) + { + var file = await botClient.ThrowIfNull() + .MakeRequestAsync(new GetFileRequest { FileId = fileId }, cancellationToken) + .ConfigureAwait(false); + + await botClient.DownloadFileAsync(filePath: file.FilePath!, destination, cancellationToken) + .ConfigureAwait(false); + + return file; + } + + /// + /// Use this method to get a list of profile pictures for a user. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns a object + public static async Task GetUserProfilePhotosAsync( + this ITelegramBotClient botClient, + GetUserProfilePhotosRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current value of the bot’s menu button in a private chat, + /// or the default menu button. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// set for the given chat id or a default one + public static async Task GetChatMenuButtonAsync( + this ITelegramBotClient botClient, + GetChatMenuButtonRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// A simple method for testing your bot’s auth token. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns basic information about the bot in form of a object. + public static async Task GetMeAsync( + this ITelegramBotClient botClient, + GetMeRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current default administrator rights of the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Default or channel + public static async Task GetMyDefaultAdministratorRightsAsync( + this ITelegramBotClient botClient, + GetMyDefaultAdministratorRightsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current bot name for the given user language. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns on success. + /// + public static async Task GetMyNameAsync( + this ITelegramBotClient botClient, + GetMyNameRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the list of boosts added to a chat by a user. + /// Requires administrator rights in the chat. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns a object. + public static async Task GetUserChatBoostsAsync( + this ITelegramBotClient botClient, + GetUserChatBoostsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to close the bot instance before moving it from one local server to another. You need to + /// delete the webhook before calling this method to ensure that the bot isn't launched again after server + /// restart. The method will return error 429 in the first 10 minutes after the bot is launched. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task CloseAsync( + this ITelegramBotClient botClient, + CloseRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to log out from the cloud Bot API server before launching the bot locally. You must + /// log out the bot before running it locally, otherwise there is no guarantee that the bot will receive + /// updates. After a successful call, you can immediately log in on a local server, but will not be able to + /// log in back to the cloud Bot API server for 10 minutes. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task LogOutAsync( + this ITelegramBotClient botClient, + LogOutRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and + /// channels, the user will not be able to return to the chat on their own using invite links, etc., unless + /// unbanned + /// first. The bot must be an administrator in the chat for this to work and must have the appropriate + /// admin rights. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task BanChatMemberAsync( + this ITelegramBotClient botClient, + BanChatMemberRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + public static async Task BanChatSenderChatAsync( + this ITelegramBotClient botClient, + BanChatSenderChatRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to approve a chat join request. The bot must be an administrator in the chat for this to + /// work and must have the administrator right. + /// Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task ApproveChatJoinRequestAsync( + this ITelegramBotClient botClient, + ApproveChatJoinRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to create an additional invite link for a chat. The bot must be an administrator + /// in the chat for this to work and must have the appropriate admin rights. The link can be revoked + /// using the method + /// RevokeChatInviteLinkAsync + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns the new invite link as object. + public static async Task CreateChatInviteLinkAsync( + this ITelegramBotClient botClient, + CreateChatInviteLinkRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to decline a chat join request. The bot must be an administrator in the chat for this to + /// work and must have the administrator right. + /// Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeclineChatJoinRequestAsync( + this ITelegramBotClient botClient, + DeclineChatJoinRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit a non-primary invite link created by the bot. The bot must be an + /// administrator in the chat for this to work and must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns the edited invite link as a object. + public static async Task EditChatInviteLinkAsync( + this ITelegramBotClient botClient, + EditChatInviteLinkRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to generate a new primary invite link for a chat; any previously generated primary + /// link is revoked. The bot must be an administrator in the chat for this to work and must have the + /// appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task ExportChatInviteLinkAsync( + this ITelegramBotClient botClient, + ExportChatInviteLinkRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to revoke an invite link created by the bot. If the primary link is revoked, a new + /// link is automatically generated. The bot must be an administrator in the chat for this to work and + /// must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns the revoked invite link as object. + public static async Task RevokeChatInviteLinkAsync( + this ITelegramBotClient botClient, + RevokeChatInviteLinkRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to close an open topic in a forum supergroup chat. The bot must be an administrator in the chat + /// for this to work and must have the administrator rights, + /// unless it is the creator of the topic. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task CloseForumTopicAsync( + this ITelegramBotClient botClient, + CloseForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to close an open 'General' topic in a forum supergroup chat. The bot must be an administrator + /// in the chat for this to work and must have the + /// administrator rights. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task CloseGeneralForumTopicAsync( + this ITelegramBotClient botClient, + CloseGeneralForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to create a topic in a forum supergroup chat. The bot must be an administrator in the chat for + /// this to work and must have the administrator rights. + /// Returns information about the created topic as a object. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns information about the created topic as a object. + /// + public static async Task CreateForumTopicAsync( + this ITelegramBotClient botClient, + CreateForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a chat photo. Photos can't be changed for private chats. The bot must be an + /// administrator in the chat for this to work and must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteChatPhotoAsync( + this ITelegramBotClient botClient, + DeleteChatPhotoRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the + /// chat for this to work and must have the appropriate admin rights. Use the field + /// optionally returned in + /// GetChatAsync + /// requests to check if the bot can use this method + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteChatStickerSetAsync( + this ITelegramBotClient botClient, + DeleteChatStickerSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a forum topic along with all its messages in a forum supergroup chat. The bot must be + /// an administrator in the chat for this to work and must have the + /// administrator rights. Returns + /// on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteForumTopicAsync( + this ITelegramBotClient botClient, + DeleteForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit name and icon of a topic in a forum supergroup chat. The bot must be an administrator + /// in the chat for this to work and must have administrator + /// rights, unless it is the creator of the topic. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditForumTopicAsync( + this ITelegramBotClient botClient, + EditForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit the name of the 'General' topic in a forum supergroup chat. The bot must be an + /// administrator in the chat for this to work and must have + /// administrator rights. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditGeneralForumTopicAsync( + this ITelegramBotClient botClient, + EditGeneralForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get a list of administrators in a chat. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// On success, returns an Array of objects that contains information about all chat + /// administrators except other bots. If the chat is a group or a supergroup and no administrators were + /// appointed, only the creator will be returned + /// + public static async Task GetChatAdministratorsAsync( + this ITelegramBotClient botClient, + GetChatAdministratorsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the number of members in a chat. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns on success. + public static async Task GetChatMemberCountAsync( + this ITelegramBotClient botClient, + GetChatMemberCountRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get information about a member of a chat. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns a object on success. + public static async Task GetChatMemberAsync( + this ITelegramBotClient botClient, + GetChatMemberRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get up to date information about the chat (current name of the user for one-on-one + /// conversations, current username of a user, group or channel, etc.) + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns a object on success. + public static async Task GetChatAsync( + this ITelegramBotClient botClient, + GetChatRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to hide the 'General' topic in a forum supergroup chat. The bot must be an administrator in the + /// chat for this to work and must have the administrator + /// rights. The topic will be automatically closed if it was open. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task HideGeneralForumTopicAsync( + this ITelegramBotClient botClient, + HideGeneralForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method for your bot to leave a group, supergroup or channel. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task LeaveChatAsync( + this ITelegramBotClient botClient, + LeaveChatRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + public static async Task PinChatMessageAsync( + this ITelegramBotClient botClient, + PinChatMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to promote or demote a user in a supergroup or a channel. The bot must be an administrator in + /// the chat for this to work and must have the appropriate admin rights. Pass for + /// all boolean parameters to demote a user. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task PromoteChatMemberAsync( + this ITelegramBotClient botClient, + PromoteChatMemberRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to reopen a closed topic in a forum supergroup chat. The bot must be an administrator in the + /// chat for this to work and must have the administrator + /// rights, unless it is the creator of the topic. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task ReopenForumTopicAsync( + this ITelegramBotClient botClient, + ReopenForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to reopen a closed 'General' topic in a forum supergroup chat. The bot must be an + /// administrator in the chat for this to work and must have the + /// administrator rights. The topic will be automatically + /// unhidden if it was hidden. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task ReopenGeneralForumTopicAsync( + this ITelegramBotClient botClient, + ReopenGeneralForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to restrict a user in a supergroup. The bot must be an administrator in the supergroup + /// for this to work and must have the appropriate admin rights. Pass for all permissions to + /// lift restrictions from a user. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task RestrictChatMemberAsync( + this ITelegramBotClient botClient, + RestrictChatMemberRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set a custom title for an administrator in a supergroup promoted by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatAdministratorCustomTitleAsync( + this ITelegramBotClient botClient, + SetChatAdministratorCustomTitleRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the description of a group, a supergroup or a channel. The bot must + /// be an administrator in the chat for this to work and must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatDescriptionAsync( + this ITelegramBotClient botClient, + SetChatDescriptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set default chat permissions for all members. The bot must be an administrator + /// in the group or a supergroup for this to work and must have the + /// admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatPermissionsAsync( + this ITelegramBotClient botClient, + SetChatPermissionsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set a new profile photo for the chat. Photos can't be changed for private chats. + /// The bot must be an administrator in the chat for this to work and must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatPhotoAsync( + this ITelegramBotClient botClient, + SetChatPhotoRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the + /// chat for this to work and must have the appropriate admin rights. Use the field + /// optionally returned in + /// GetChatAsync + /// request to check if the bot can use this method. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatStickerSetAsync( + this ITelegramBotClient botClient, + SetChatStickerSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the title of a chat. Titles can't be changed for private chats. The bot + /// must be an administrator in the chat for this to work and must have the appropriate admin rights + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatTitleAsync( + this ITelegramBotClient botClient, + SetChatTitleRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to unban a previously banned user in a supergroup or channel. The user will not + /// return to the group or channel automatically, but will be able to join via link, etc. The bot must be an + /// administrator for this to work. By default, this method guarantees that after the call the user is not a + /// member of the chat, but will be able to join it. So if the user is a member of the chat they will also be + /// removed from the chat. + /// If you don't want this, use the property + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnbanChatMemberAsync( + this ITelegramBotClient botClient, + UnbanChatMemberRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to unban a previously banned channel chat in a supergroup or channel. The bot must be + /// an administrator for this to work and must have the appropriate administrator rights. + /// Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnbanChatSenderChatAsync( + this ITelegramBotClient botClient, + UnbanChatSenderChatRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to uhhide the 'General' topic in a forum supergroup chat. The bot must be an administrator + /// in the chat for this to work and must have the + /// administrator rights. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnhideGeneralForumTopicAsync( + this ITelegramBotClient botClient, + UnhideGeneralForumTopicRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to clear the list of pinned messages in a chat. If the chat is not a private chat, + /// the bot must be an administrator in the chat for this to work and must have the + /// '' admin right in a supergroup or + /// '' admin right in a channel + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnpinAllChatMessagesAsync( + this ITelegramBotClient botClient, + UnpinAllChatMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to clear the list of pinned messages in a forum topic. The bot must be an administrator in the + /// chat for this to work and must have the administrator + /// right in the supergroup. Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnpinAllForumTopicMessagesAsync( + this ITelegramBotClient botClient, + UnpinAllForumTopicMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to clear the list of pinned messages in a General forum topic. The bot must be an administrator + /// in the chat for this to work and must have the + /// administrator right in the supergroup. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnpinAllGeneralForumTopicMessagesAsync( + this ITelegramBotClient botClient, + UnpinAllGeneralForumTopicMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to remove a message from the list of pinned messages in a chat. If the chat is not + /// a private chat, the bot must be an administrator in the chat for this to work and must have the + /// '' admin right in a supergroup or + /// '' admin right in a channel + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task UnpinChatMessageAsync( + this ITelegramBotClient botClient, + UnpinChatMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. + /// The method is analogous to the method + /// , but the + /// copied message doesn't have a link to the original message. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns the of the sent message on success. + public static async Task CopyMessageAsync( + this ITelegramBotClient botClient, + CopyMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to copy messages of any kind. If some of the specified messages can't be found or copied, + /// they are skipped. Service messages, giveaway messages, giveaway winners messages, and invoice messages + /// can't be copied. A quiz can be copied only if the value of the field + /// CorrectOptionId is known to the bot. The method is analogous + /// to the method + /// , but the + /// copied messages don't have a link to the original message. Album grouping is kept for copied messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, an array of of the sent messages is returned. + public static async Task CopyMessagesAsync( + this ITelegramBotClient botClient, + CopyMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to forward messages of any kind. Service messages can't be forwarded. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task ForwardMessageAsync( + this ITelegramBotClient botClient, + ForwardMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to forward multiple messages of any kind. If some of the specified messages can't be found + /// or forwarded, they are skipped. Service messages and messages with protected content can't be forwarded. + /// Album grouping is kept for forwarded messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, an array of of the sent messages is returned. + public static async Task ForwardMessagesAsync( + this ITelegramBotClient botClient, + ForwardMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit live location messages. A location can be edited until its + /// expires or editing is explicitly disabled by a call to + /// . + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditMessageLiveLocationAsync( + this ITelegramBotClient botClient, + EditInlineMessageLiveLocationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit live location messages. A location can be edited until its + /// expires or editing is explicitly disabled by a call to + /// . + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the edited is returned. + public static async Task EditMessageLiveLocationAsync( + this ITelegramBotClient botClient, + EditMessageLiveLocationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send point on the map. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendLocationAsync( + this ITelegramBotClient botClient, + SendLocationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send information about a venue. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + /// + public static async Task SendVenueAsync( + this ITelegramBotClient botClient, + SendVenueRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to stop updating a live location message before + /// expires. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task StopMessageLiveLocationAsync( + this ITelegramBotClient botClient, + StopInlineMessageLiveLocationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to stop updating a live location message before + /// expires. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the sent is returned. + public static async Task StopMessageLiveLocationAsync( + this ITelegramBotClient botClient, + StopMessageLiveLocationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send animation files (GIF or H.264/MPEG-4 AVC video without sound). Bots can currently + /// send animation files of up to 50 MB in size, this limit may be changed in the future. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendAnimationAsync( + this ITelegramBotClient botClient, + SendAnimationRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send audio files, if you want Telegram clients to display them in the music player. + /// Your audio must be in the .MP3 or .M4A format. Bots can currently send audio files of up to 50 MB in size, + /// this limit may be changed in the future. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendAudioAsync( + this ITelegramBotClient botClient, + SendAudioRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method when you need to tell the user that something is happening on the bot’s side. The status is + /// set for 5 seconds or less (when a message arrives from your bot, Telegram clients clear its typing status). + /// + /// + /// + /// The ImageBot needs some time to process a request and upload the + /// image. Instead of sending a text message along the lines of “Retrieving image, please wait…”, the bot may use + /// SendChatActionAsync + /// with = . The user will see a + /// “sending photo” status for the bot. + /// + /// + /// We only recommend using this method when a response from the bot will take a noticeable amount of + /// time to arrive. + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SendChatActionAsync( + this ITelegramBotClient botClient, + SendChatActionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send phone contacts. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendContactAsync( + this ITelegramBotClient botClient, + SendContactRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send an animated emoji that will display a random value. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendDiceAsync( + this ITelegramBotClient botClient, + SendDiceRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send general files. Bots can currently send files of any type of up to 50 MB in size, + /// this limit may be changed in the future. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendDocumentAsync( + this ITelegramBotClient botClient, + SendDocumentRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send a group of photos, videos, documents or audios as an album. Documents and audio + /// files can be only grouped in an album with messages of the same type. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, an array of s that were sent is returned. + public static async Task SendMediaGroupAsync( + this ITelegramBotClient botClient, + SendMediaGroupRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send text messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendMessageAsync( + this ITelegramBotClient botClient, + SendMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send photos. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendPhotoAsync( + this ITelegramBotClient botClient, + SendPhotoRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send a native poll. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendPollAsync( + this ITelegramBotClient botClient, + SendPollRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// As of v.4.0, Telegram clients + /// support rounded square mp4 videos of up to 1 minute long. Use this method to send video messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendVideoNoteAsync( + this ITelegramBotClient botClient, + SendVideoNoteRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send video files, Telegram clients support mp4 videos (other formats may be sent as + /// ). Bots can currently send video files of up to 50 MB in size, this limit may be + /// changed in the future. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendVideoAsync( + this ITelegramBotClient botClient, + SendVideoRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send audio files, if you want Telegram clients to display the file as a playable voice + /// message. For this to work, your audio must be in an .OGG file encoded with OPUS (other formats may be sent + /// as or ). Bots can currently send voice messages of up to 50 MB + /// in size, this limit may be changed in the future. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendVoiceAsync( + this ITelegramBotClient botClient, + SendVoiceRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the chosen reactions on a message. Service messages can't be reacted to. + /// Automatically forwarded messages from a channel to its discussion group have the same + /// available reactions as messages in the channel. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMessageReactionAsync( + this ITelegramBotClient botClient, + SetMessageReactionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the bot’s menu button in a private chat, or the default menu button. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetChatMenuButtonAsync( + this ITelegramBotClient botClient, + SetChatMenuButtonRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the default administrator rights requested by the bot when it's added as an + /// administrator to groups or channels. These rights will be suggested to users, but they are free to modify + /// the list before adding the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMyDefaultAdministratorRightsAsync( + this ITelegramBotClient botClient, + SetMyDefaultAdministratorRightsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the bot's name. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetMyNameAsync( + this ITelegramBotClient botClient, + SetMyNameRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get the current bot short description + /// for the given user language. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns on success. + /// + public static async Task GetMyShortDescriptionAsync( + this ITelegramBotClient botClient, + GetMyShortDescriptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the bot's short description,which is shown on + /// the bot's profile page and is sent together with the link when users share the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + public static async Task SetMyShortDescriptionAsync( + this ITelegramBotClient botClient, + SetMyShortDescriptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get data for high score tables. Will return the score of the specified user and + /// several of their neighbors in a game. + /// + /// + /// This method will currently return scores for the target user, plus two of their closest neighbors on + /// each side. Will also return the top three users if the user and his neighbors are not among them. + /// Please note that this behavior is subject to change. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, returns an Array of objects. + public static async Task GetGameHighScoresAsync( + this ITelegramBotClient botClient, + GetGameHighScoresRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get data for high score tables. Will return the score of the specified user and + /// several of their neighbors in a game. + /// + /// + /// This method will currently return scores for the target user, plus two of their closest neighbors + /// on each side. Will also return the top three users if the user and his neighbors are not among them. + /// Please note that this behavior is subject to change. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, returns an Array of objects. + public static async Task GetGameHighScoresAsync( + this ITelegramBotClient botClient, + GetInlineGameHighScoresRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send a game. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendGameAsync( + this ITelegramBotClient botClient, + SendGameRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the score of the specified user in a game. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// On success returns the edited . Returns an error, if the new score is not greater + /// than the user's current score in the chat and is + /// + public static async Task SetGameScoreAsync( + this ITelegramBotClient botClient, + SetGameScoreRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the score of the specified user in a game. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns an error, if the new score is not greater than the user's current score in the chat and + /// is + /// + public static async Task SetGameScoreAsync( + this ITelegramBotClient botClient, + SetInlineGameScoreRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to remove webhook integration if you decide to switch back to + /// GetUpdatesAsync + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns on success + public static async Task DeleteWebhookAsync( + this ITelegramBotClient botClient, + DeleteWebhookRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to receive incoming updates using long polling + /// (wiki) + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// + /// This method will not work if an outgoing webhook is set up + /// + /// In order to avoid getting duplicate updates, recalculate after each server + /// response + /// + /// + /// + /// An Array of objects is returned. + public static async Task GetUpdatesAsync( + this ITelegramBotClient botClient, + GetUpdatesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get current webhook status. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// On success, returns a object. If the bot is using + /// , will return an object + /// with the field empty. + /// + public static async Task GetWebhookInfoAsync( + this ITelegramBotClient botClient, + GetWebhookInfoRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to specify a URL and receive incoming updates via an outgoing webhook. + /// Whenever there is an update for the bot, we will send an HTTPS POST request to the + /// specified URL, containing a JSON-serialized . In case of + /// an unsuccessful request, we will give up after a reasonable amount of attempts. + /// Returns on success. + /// + /// If you'd like to make sure that the webhook was set by you, you can specify secret data + /// in the parameter . If specified, the request + /// will contain a header X-Telegram-Bot-Api-Secret-Token with the secret token as content. + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// + /// + /// You will not be able to receive updates using + /// for as long as an + /// outgoing webhook is set up + /// + /// + /// To use a self-signed certificate, you need to upload your + /// public key certificate using + /// parameter. Please upload as , + /// sending a string will not work + /// + /// Ports currently supported for webhooks: 443, 80, 88, 8443 + /// + /// If you're having any trouble setting up webhooks, please check out this + /// amazing guide to Webhooks. + /// + + public static async Task SetWebhookAsync( + this ITelegramBotClient botClient, + SetWebhookRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send answers to an inline query. + /// + /// + /// No more than 50 results per query are allowed. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerInlineQueryAsync( + this ITelegramBotClient botClient, + AnswerInlineQueryRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the result of an interaction with a Web App and send a corresponding message on + /// behalf of the user to the chat from which the query originated. On success, a + /// object is returned. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerWebAppQueryAsync( + this ITelegramBotClient botClient, + AnswerWebAppQueryRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Once the user has confirmed their payment and shipping details, the Bot API sends the final confirmation + /// in the form of an with the field . + /// Use this method to respond to such pre-checkout queries. + /// + /// + /// Note: The Bot API must receive an answer within 10 seconds after the pre-checkout query was sent. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerPreCheckoutQueryAsync( + this ITelegramBotClient botClient, + AnswerPreCheckoutQueryRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// If you sent an invoice requesting a shipping address and the parameter isFlexible" was specified, + /// the Bot API will send an with a field + /// to the bot. Use this method to reply to shipping queries + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AnswerShippingQueryAsync( + this ITelegramBotClient botClient, + AnswerShippingQueryRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to create a link for an invoice. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task CreateInvoiceLinkAsync( + this ITelegramBotClient botClient, + CreateInvoiceLinkRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send invoices. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the sent is returned. + public static async Task SendInvoiceAsync( + this ITelegramBotClient botClient, + SendInvoiceRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to add a new sticker to a set created by the bot. + /// The format of the added sticker must match the format of the other stickers in the set. + /// + /// + /// Emoji sticker sets can have up to 200 stickers. + /// + /// + /// Animated and video sticker sets can have up to 50 stickers. + /// + /// + /// Static sticker sets can have up to 120 stickers. + /// + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task AddStickerToSetAsync( + this ITelegramBotClient botClient, + AddStickerToSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to create a new sticker set owned by a user. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task CreateNewStickerSetAsync( + this ITelegramBotClient botClient, + CreateNewStickerSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a sticker from a set created by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteStickerFromSetAsync( + this ITelegramBotClient botClient, + DeleteStickerFromSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a sticker set that was created by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteStickerSetAsync( + this ITelegramBotClient botClient, + DeleteStickerSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get information about custom emoji stickers by their identifiers. + /// Returns an Array of objects. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, a object is returned. + public static async Task GetCustomEmojiStickersAsync( + this ITelegramBotClient botClient, + GetCustomEmojiStickersRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get custom emoji stickers, which can be used as a forum topic icon by any user. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// Returns an Array of objects. + public static async Task GetForumTopicIconStickersAsync( + this ITelegramBotClient botClient, + GetForumTopicIconStickersRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to get a sticker set. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// On success, a object is returned. + /// + public static async Task GetStickerSetAsync( + this ITelegramBotClient botClient, + GetStickerSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to send static .WEBP, animated .TGS, or video .WEBM stickers. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// On success, the sent is returned. + /// + public static async Task SendStickerAsync( + this ITelegramBotClient botClient, + SendStickerRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the thumbnail of a custom emoji sticker set. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetCustomEmojiStickerSetThumbnailAsync( + this ITelegramBotClient botClient, + SetCustomEmojiStickerSetThumbnailRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the list of emoji assigned to a regular or custom emoji sticker. + /// The sticker must belong to a sticker set created by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerEmojiListAsync( + this ITelegramBotClient botClient, + SetStickerEmojiListRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change search keywords assigned to a regular or custom emoji sticker. + /// The sticker must belong to a sticker set created by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerKeywordsAsync( + this ITelegramBotClient botClient, + SetStickerKeywordsRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to change the mask position of a mask sticker. + /// The sticker must belong to a sticker set that was created by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerMaskPositionAsync( + this ITelegramBotClient botClient, + SetStickerMaskPositionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to move a sticker in a set created by the bot to a specific position. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerPositionInSetAsync( + this ITelegramBotClient botClient, + SetStickerPositionInSetRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the thumbnail of a regular or mask sticker set. + /// The format of the thumbnail file must match the format of the stickers in the set. + /// Returns on success. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerSetThumbnailAsync( + this ITelegramBotClient botClient, + SetStickerSetThumbnailRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to set the title of a created sticker set. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task SetStickerSetTitleAsync( + this ITelegramBotClient botClient, + SetStickerSetTitleRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to upload a file with a sticker for later use in the + /// and + /// methods (the file can be used multiple times). + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// + /// Returns the uploaded on success. + /// + public static async Task UploadStickerFileAsync( + this ITelegramBotClient botClient, + UploadStickerFileRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete a message, including service messages, with the following limitations: + /// + /// A message can only be deleted if it was sent less than 48 hours ago + /// A dice message in a private chat can only be deleted if it was sent more than 24 hours ago + /// Bots can delete outgoing messages in private chats, groups, and supergroups + /// Bots can delete incoming messages in private chats + /// Bots granted can_post_messages permissions can delete outgoing messages in channels + /// If the bot is an administrator of a group, it can delete any message there + /// + /// If the bot has can_delete_messages permission in a supergroup or a channel, it can delete any message there + /// + /// + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteMessageAsync( + this ITelegramBotClient botClient, + DeleteMessageRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to delete multiple messages simultaneously. + /// If some of the specified messages can't be found, they are skipped. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task DeleteMessagesAsync( + this ITelegramBotClient botClient, + DeleteMessagesRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit captions of messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditMessageCaptionAsync( + this ITelegramBotClient botClient, + EditInlineMessageCaptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit animation, audio, document, photo, or video messages. If a message is part of + /// a message album, then it can be edited only to an audio for audio albums, only to a document for document + /// albums and to a photo or a video otherwise. Use a previously uploaded file via its + /// or specify a URL + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditMessageMediaAsync( + this ITelegramBotClient botClient, + EditInlineMessageMediaRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit only the reply markup of messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditMessageReplyMarkupAsync( + this ITelegramBotClient botClient, + EditInlineMessageReplyMarkupRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit text and game messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + public static async Task EditMessageTextAsync( + this ITelegramBotClient botClient, + EditInlineMessageTextRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit captions of messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the edited is returned. + public static async Task EditMessageCaptionAsync( + this ITelegramBotClient botClient, + EditMessageCaptionRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit animation, audio, document, photo, or video messages. If a message is part of + /// a message album, then it can be edited only to an audio for audio albums, only to a document for document + /// albums and to a photo or a video otherwise. Use a previously uploaded file via its + /// or specify a URL + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the edited is returned. + public static async Task EditMessageMediaAsync( + this ITelegramBotClient botClient, + EditMessageMediaRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit only the reply markup of messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the edited is returned. + public static async Task EditMessageReplyMarkupAsync( + this ITelegramBotClient botClient, + EditMessageReplyMarkupRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to edit text and game messages. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success the edited is returned. + public static async Task EditMessageTextAsync( + this ITelegramBotClient botClient, + EditMessageTextRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); + + /// + /// Use this method to stop a poll which was sent by the bot. + /// + /// An instance of + /// Request parameters + /// + /// A cancellation token that can be used by other objects or threads to receive notice of cancellation + /// + /// On success, the stopped with the final results is returned. + public static async Task StopPollAsync( + this ITelegramBotClient botClient, + StopPollRequest request, + CancellationToken cancellationToken = default + ) => + await botClient.ThrowIfNull() + .MakeRequestAsync(request, cancellationToken) + .ConfigureAwait(false); +} From dabf07785ce4df37e2d873ade61a28a42cc2ef47 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 08:58:51 +0400 Subject: [PATCH 77/90] Mark old API methods with positional parameters as obsolete --- CHANGELOG.md | 2 + .../TelegramBotClientExtensions.ApiMethods.cs | 161 ++++++++++++++---- 2 files changed, 133 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e82656db..cd30a98dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). ### Added +- API methods on `ITelegramBotClient` that accept request classes with parameters - Class `UnpinAllGeneralForumTopicMessagesRequest` - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. - Enum `ReactionTypeKind` @@ -73,6 +74,7 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Fields `Chat` and `Id` to type `Story` ### Changed +- All API methods with positional parameters on `ITelegramBotClient` are marked obsolete - Class `UnpinAllGeneralForumTopicMessages` marked as obsolete - Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods - `ITelegramBotClient.CopyMessageAsync`, diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 42376ac3a..2df55f61d 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -60,6 +60,7 @@ public static partial class TelegramBotClientExtensions /// /// /// An Array of objects is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetUpdatesAsync( this ITelegramBotClient botClient, int? offset = default, @@ -147,6 +148,7 @@ await botClient.ThrowIfNull() /// If you're having any trouble setting up webhooks, please check out this /// amazing guide to Webhooks. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetWebhookAsync( this ITelegramBotClient botClient, string url, @@ -184,6 +186,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns true on success + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteWebhookAsync( this ITelegramBotClient botClient, bool? dropPendingUpdates = default, @@ -207,6 +210,7 @@ await botClient.ThrowIfNull() /// On success, returns a object. If the bot is using , /// will return an object with the field empty. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetWebhookInfoAsync( this ITelegramBotClient botClient, CancellationToken cancellationToken = default @@ -227,6 +231,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns basic information about the bot in form of a object. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMeAsync( this ITelegramBotClient botClient, CancellationToken cancellationToken = default @@ -245,6 +250,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task LogOutAsync( this ITelegramBotClient botClient, CancellationToken cancellationToken = default @@ -262,6 +268,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CloseAsync( this ITelegramBotClient botClient, CancellationToken cancellationToken = default @@ -307,6 +314,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the method SendMessageAsync instead")] public static async Task SendTextMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -364,6 +372,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ForwardMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -420,6 +429,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, an array of of the sent messages is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ForwardMessagesAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -491,6 +501,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns the of the sent message on success. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CopyMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -563,6 +574,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, an array of of the sent messages is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CopyMessagesAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -638,6 +650,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendPhotoAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -726,6 +739,7 @@ await botClient.ThrowIfNull(). /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendAudioAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -822,6 +836,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendDocumentAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -918,6 +933,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendVideoAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1021,6 +1037,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendAnimationAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1109,6 +1126,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendVoiceAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1185,6 +1203,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendVideoNoteAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1240,6 +1259,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, an array of s that were sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendMediaGroupAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1305,6 +1325,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendLocationAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1375,6 +1396,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the edited is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageLiveLocationAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1432,6 +1454,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageLiveLocationAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -1479,6 +1502,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task StopMessageLiveLocationAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1513,6 +1537,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task StopMessageLiveLocationAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -1571,6 +1596,7 @@ await botClient.ThrowIfNull() /// /// On success, the sent is returned. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendVenueAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1642,6 +1668,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendContactAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1739,6 +1766,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendPollAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1822,6 +1850,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendDiceAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1886,6 +1915,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendChatActionAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1929,6 +1959,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMessageReactionAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -1964,6 +1995,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns a object + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetUserProfilePhotosAsync( this ITelegramBotClient botClient, long userId, @@ -2000,6 +2032,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, a object is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetFileAsync( this ITelegramBotClient botClient, string fileId, @@ -2012,33 +2045,6 @@ await botClient.ThrowIfNull() ) .ConfigureAwait(false); - /// - /// Use this method to get basic info about a file download it. For the moment, bots can download files - /// of up to 20MB in size. - /// - /// An instance of - /// File identifier to get info about - /// Destination stream to write file to - /// - /// A cancellation token that can be used by other objects or threads to receive notice of cancellation - /// - /// On success, a object is returned. - public static async Task GetInfoAndDownloadFileAsync( - this ITelegramBotClient botClient, - string fileId, - Stream destination, - CancellationToken cancellationToken = default) - { - var file = await botClient.ThrowIfNull() - .MakeRequestAsync(new GetFileRequest { FileId = fileId }, cancellationToken) - .ConfigureAwait(false); - - await botClient.DownloadFileAsync(filePath: file.FilePath!, destination, cancellationToken) - .ConfigureAwait(false); - - return file; - } - /// /// Use this method to ban a user in a group, a supergroup or a channel. In the case of supergroups and /// channels, the user will not be able to return to the chat on their own using invite links, etc., unless @@ -2064,6 +2070,7 @@ await botClient.DownloadFileAsync(filePath: file.FilePath!, destination, cancell /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task BanChatMemberAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2102,6 +2109,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnbanChatMemberAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2147,6 +2155,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task RestrictChatMemberAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2234,6 +2243,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task PromoteChatMemberAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2296,6 +2306,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatAdministratorCustomTitleAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2330,6 +2341,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task BanChatSenderChatAsync(this ITelegramBotClient botClient, ChatId chatId, long senderChatId, @@ -2360,6 +2372,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnbanChatSenderChatAsync(this ITelegramBotClient botClient, ChatId chatId, long senderChatId, @@ -2399,6 +2412,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatPermissionsAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2431,6 +2445,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ExportChatInviteLinkAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2470,6 +2485,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns the new invite link as object. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CreateChatInviteLinkAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2517,6 +2533,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns the edited invite link as a object. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditChatInviteLinkAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2557,6 +2574,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns the revoked invite link as object. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task RevokeChatInviteLinkAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2588,6 +2606,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ApproveChatJoinRequest( this ITelegramBotClient botClient, ChatId chatId, @@ -2619,6 +2638,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeclineChatJoinRequest( this ITelegramBotClient botClient, ChatId chatId, @@ -2649,6 +2669,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatPhotoAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2676,6 +2697,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteChatPhotoAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2701,6 +2723,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatTitleAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2731,6 +2754,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatDescriptionAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2747,7 +2771,7 @@ await botClient.ThrowIfNull() /// /// Use this method to add a message to the list of pinned messages in a chat. If the chat is not a private /// chat, the bot must be an administrator in the chat for this to work and must have the - /// '' admin right in a supergroup or + /// '' admin right in a supergroup or /// '' admin right in a channel /// /// An instance of @@ -2763,6 +2787,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task PinChatMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2800,6 +2825,7 @@ await botClient.ThrowIfNull(). /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnpinChatMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2827,6 +2853,7 @@ await botClient.ThrowIfNull(). /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnpinAllChatMessages( this ITelegramBotClient botClient, ChatId chatId, @@ -2847,6 +2874,7 @@ await botClient.ThrowIfNull(). /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task LeaveChatAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2869,6 +2897,7 @@ await botClient.ThrowIfNull(). /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns a object on success. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetChatAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2894,6 +2923,7 @@ await botClient.ThrowIfNull() /// administrators except other bots. If the chat is a group or a supergroup and no administrators were /// appointed, only the creator will be returned /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetChatAdministratorsAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2914,7 +2944,8 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - /// Returns on success.. + /// Returns on success. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetChatMemberCountAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2937,6 +2968,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns a object on success. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetChatMemberAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2965,6 +2997,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatStickerSetAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -2992,6 +3025,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteChatStickerSetAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3009,6 +3043,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns an Array of objects. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetForumTopicIconStickersAsync( this ITelegramBotClient botClient, CancellationToken cancellationToken = default @@ -3042,6 +3077,7 @@ await botClient.ThrowIfNull() /// /// Returns information about the created topic as a object. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CreateForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3085,6 +3121,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3120,6 +3157,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CloseForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3147,6 +3185,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ReopenForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3175,6 +3214,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3202,6 +3242,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnpinAllForumTopicMessagesAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3229,6 +3270,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditGeneralForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3255,6 +3297,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CloseGeneralForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3278,6 +3321,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task ReopenGeneralForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3300,6 +3344,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task HideGeneralForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3322,6 +3367,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnhideGeneralForumTopicAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3344,13 +3390,14 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UnpinAllGeneralForumTopicMessagesAsync( this ITelegramBotClient botClient, ChatId chatId, CancellationToken cancellationToken = default ) => await botClient.ThrowIfNull() - .MakeRequestAsync(new UnpinAllGeneralForumTopicMessages { ChatId = chatId }, cancellationToken) + .MakeRequestAsync(new UnpinAllGeneralForumTopicMessagesRequest { ChatId = chatId }, cancellationToken) .ConfigureAwait(false); /// @@ -3388,6 +3435,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerCallbackQueryAsync( this ITelegramBotClient botClient, string callbackQueryId, @@ -3426,6 +3474,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Returns a object. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetUserChatBoostsAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3455,6 +3504,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMyCommandsAsync( this ITelegramBotClient botClient, IEnumerable commands, @@ -3492,6 +3542,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteMyCommandsAsync( this ITelegramBotClient botClient, BotCommandScope? scope = default, @@ -3526,6 +3577,7 @@ await botClient.ThrowIfNull() /// /// Returns Array of on success. If commands aren't set, an empty list is returned /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMyCommandsAsync( this ITelegramBotClient botClient, BotCommandScope? scope = default, @@ -3557,6 +3609,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMyNameAsync( this ITelegramBotClient botClient, string? name = default, @@ -3583,6 +3636,7 @@ await botClient.ThrowIfNull() /// /// Returns on success. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMyNameAsync( this ITelegramBotClient botClient, string? languageCode = default, @@ -3611,6 +3665,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMyDescriptionAsync( this ITelegramBotClient botClient, string? description = default, @@ -3638,6 +3693,7 @@ await botClient.ThrowIfNull() /// /// Returns on success. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMyDescriptionAsync( this ITelegramBotClient botClient, string? languageCode = default, @@ -3667,6 +3723,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMyShortDescriptionAsync( this ITelegramBotClient botClient, string? shortDescription = default, @@ -3698,6 +3755,7 @@ await botClient.ThrowIfNull() /// /// Returns on success. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMyShortDescriptionAsync( this ITelegramBotClient botClient, string? languageCode = default, @@ -3723,6 +3781,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetChatMenuButtonAsync( this ITelegramBotClient botClient, long? chatId = default, @@ -3748,6 +3807,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// set for the given chat id or a default one + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetChatMenuButtonAsync( this ITelegramBotClient botClient, long? chatId = default, @@ -3777,6 +3837,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetMyDefaultAdministratorRightsAsync( this ITelegramBotClient botClient, ChatAdministratorRights? rights = default, @@ -3806,6 +3867,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// Default or channel + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetMyDefaultAdministratorRightsAsync( this ITelegramBotClient botClient, bool? forChannels = default, @@ -3852,6 +3914,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the edited is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageTextAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -3904,6 +3967,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageTextAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -3958,6 +4022,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the edited is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageCaptionAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4007,6 +4072,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageCaptionAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -4053,6 +4119,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the edited is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageMediaAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4092,6 +4159,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageMediaAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -4130,6 +4198,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success the edited is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageReplyMarkupAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4163,6 +4232,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task EditMessageReplyMarkupAsync( this ITelegramBotClient botClient, string inlineMessageId, @@ -4199,6 +4269,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the stopped with the final results is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task StopPollAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4241,6 +4312,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteMessageAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4267,6 +4339,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteMessagesAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4327,6 +4400,7 @@ await botClient.ThrowIfNull() /// /// On success, the sent is returned. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendStickerAsync( this ITelegramBotClient botClient, ChatId chatId, @@ -4371,6 +4445,7 @@ await botClient.ThrowIfNull() /// /// On success, a object is returned. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetStickerSetAsync( this ITelegramBotClient botClient, string name, @@ -4391,6 +4466,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, a object is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetCustomEmojiStickersAsync( this ITelegramBotClient botClient, IEnumerable customEmojiIds, @@ -4426,6 +4502,7 @@ await botClient.ThrowIfNull() /// /// Returns the uploaded on success. /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task UploadStickerFileAsync( this ITelegramBotClient botClient, long userId, @@ -4482,6 +4559,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CreateNewStickerSetAsync( this ITelegramBotClient botClient, long userId, @@ -4540,6 +4618,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AddStickerToSetAsync( this ITelegramBotClient botClient, long userId, @@ -4565,6 +4644,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerPositionInSetAsync( this ITelegramBotClient botClient, InputFileId sticker, @@ -4588,6 +4668,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteStickerFromSetAsync( this ITelegramBotClient botClient, InputFileId sticker, @@ -4616,6 +4697,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerEmojiListAsync( this ITelegramBotClient botClient, InputFileId sticker, @@ -4646,6 +4728,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerKeywordsAsync( this ITelegramBotClient botClient, InputFileId sticker, @@ -4676,6 +4759,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerMaskPositionAsync( this ITelegramBotClient botClient, InputFileId sticker, @@ -4704,6 +4788,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerSetTitleAsync( this ITelegramBotClient botClient, string name, @@ -4745,6 +4830,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetStickerSetThumbnailAsync( this ITelegramBotClient botClient, string name, @@ -4775,6 +4861,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetCustomEmojiStickerSetThumbnailAsync( this ITelegramBotClient botClient, string name, @@ -4800,6 +4887,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task DeleteStickerSetAsync( this ITelegramBotClient botClient, string name, @@ -4840,6 +4928,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerInlineQueryAsync( this ITelegramBotClient botClient, string inlineQueryId, @@ -4878,6 +4967,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerWebAppQueryAsync( this ITelegramBotClient botClient, string webAppQueryId, @@ -4983,6 +5073,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendInvoiceAsync( this ITelegramBotClient botClient, long chatId, @@ -5113,6 +5204,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task CreateInvoiceLinkAsync( this ITelegramBotClient botClient, string title, @@ -5179,6 +5271,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerShippingQueryAsync( this ITelegramBotClient botClient, string shippingQueryId, @@ -5207,6 +5300,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerShippingQueryAsync( this ITelegramBotClient botClient, string shippingQueryId, @@ -5233,6 +5327,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerPreCheckoutQueryAsync( this ITelegramBotClient botClient, string preCheckoutQueryId, @@ -5258,6 +5353,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task AnswerPreCheckoutQueryAsync( this ITelegramBotClient botClient, string preCheckoutQueryId, @@ -5302,6 +5398,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, the sent is returned. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SendGameAsync( this ITelegramBotClient botClient, long chatId, @@ -5351,6 +5448,7 @@ await botClient.ThrowIfNull() /// On success returns the edited . Returns an error, if the new score is not greater /// than the user's current score in the chat and is /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetGameScoreAsync( this ITelegramBotClient botClient, long userId, @@ -5397,6 +5495,7 @@ await botClient.ThrowIfNull() /// Returns an error, if the new score is not greater than the user's current score in the chat and /// is /// + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task SetGameScoreAsync( this ITelegramBotClient botClient, long userId, @@ -5437,6 +5536,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, returns an Array of objects. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetGameHighScoresAsync( this ITelegramBotClient botClient, long userId, @@ -5472,6 +5572,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, returns an Array of objects. + [Obsolete("Use the overload that accepts the corresponding request class")] public static async Task GetGameHighScoresAsync( this ITelegramBotClient botClient, long userId, From 2b24205aa93e989c350fdc8376e96aeb62170587 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 25 Feb 2024 08:59:16 +0400 Subject: [PATCH 78/90] Fix message on obsolete attributes --- .../AnswerCallbackQueryRequest.cs | 2 +- .../Commands/SetMyCommandsRequest.cs | 2 +- .../Get Files/GetFileRequest.cs | 2 +- .../Get Files/GetUserProfilePhotosRequest.cs | 2 +- .../GetUserChatBoostsRequest.cs | 2 +- .../Manage Chat/BanChatMemberRequest.cs | 2 +- .../Manage Chat/BanChatSenderChatRequest.cs | 2 +- .../ApproveChatJoinRequest.cs | 2 +- .../CreateChatInviteLinkRequest.cs | 2 +- .../DeclineChatJoinRequest.cs | 2 +- .../EditChatInviteLinkRequest.cs | 2 +- .../ExportChatInviteLinkRequest.cs | 2 +- .../RevokeChatInviteLinkRequest.cs | 2 +- .../Manage Chat/CloseForumTopicRequest.cs | 2 +- .../CloseGeneralForumTopicRequest.cs | 2 +- .../Manage Chat/CreateForumTopicRequest.cs | 2 +- .../Manage Chat/DeleteChatPhotoRequest.cs | 2 +- .../DeleteChatStickerSetRequest.cs | 2 +- .../Manage Chat/DeleteForumTopicRequest.cs | 2 +- .../Manage Chat/EditForumTopicRequest.cs | 2 +- .../EditGeneralForumTopicRequest.cs | 2 +- .../Get Chat/GetChatAdministratorsRequest.cs | 2 +- .../Get Chat/GetChatMemberCountRequest.cs | 2 +- .../Get Chat/GetChatMemberRequest.cs | 2 +- .../Manage Chat/Get Chat/GetChatRequest.cs | 2 +- .../HideGeneralForumTopicRequest.cs | 2 +- .../Manage Chat/LeaveChatRequest.cs | 2 +- .../Manage Chat/PinChatMessageRequest.cs | 2 +- .../Manage Chat/PromoteChatMemberRequest.cs | 2 +- .../Manage Chat/ReopenForumTopicRequest.cs | 2 +- .../ReopenGeneralForumTopicRequest.cs | 2 +- .../Manage Chat/RestrictChatMemberRequest.cs | 2 +- .../SetChatAdministratorCustomTitleRequest.cs | 2 +- .../Manage Chat/SetChatDescriptionRequest.cs | 2 +- .../Manage Chat/SetChatPermissionsRequest.cs | 2 +- .../Manage Chat/SetChatPhotoRequest.cs | 2 +- .../Manage Chat/SetChatStickerSetRequest.cs | 2 +- .../Manage Chat/SetChatTitleRequest.cs | 2 +- .../Manage Chat/UnbanChatMemberRequest.cs | 2 +- .../Manage Chat/UnbanChatSenderChatRequest.cs | 2 +- .../UnhideGeneralForumTopicRequest.cs | 2 +- .../UnpinAllChatMessagesRequest.cs | 2 +- .../UnpinAllForumTopicMessagesRequest.cs | 2 +- .../Manage Chat/UnpinChatMessageRequest.cs | 2 +- .../Messages/CopyMessageRequest.cs | 2 +- .../Messages/CopyMessagesRequest.cs | 2 +- .../Messages/ForwardMessageRequest.cs | 2 +- .../Messages/ForwardMessagesRequest.cs | 2 +- .../EditInlineMessageLiveLocationRequest.cs | 2 +- .../EditMessageLiveLocationRequest.cs | 2 +- .../Messages/Location/SendLocationRequest.cs | 2 +- .../Messages/Location/SendVenueRequest.cs | 2 +- .../StopInlineMessageLiveLocationRequest.cs | 2 +- .../StopMessageLiveLocationRequest.cs | 2 +- .../Messages/SendAnimationRequest.cs | 2 +- .../Messages/SendAudioRequest.cs | 2 +- .../Messages/SendChatActionRequest.cs | 2 +- .../Messages/SendContactRequest.cs | 2 +- .../Messages/SendDiceRequest.cs | 2 +- .../Messages/SendDocumentRequest.cs | 2 +- .../Messages/SendMediaGroupRequest.cs | 2 +- .../Messages/SendMessageRequest.cs | 2 +- .../Messages/SendPhotoRequest.cs | 2 +- .../Messages/SendPollRequest.cs | 2 +- .../Messages/SendVideoNoteRequest.cs | 2 +- .../Messages/SendVideoRequest.cs | 2 +- .../Messages/SendVoiceRequest.cs | 2 +- .../Messages/SetMessageReactionRequest.cs | 2 +- .../Games/GetGameHighScoresRequest.cs | 2 +- .../Games/GetInlineGameHighScoresRequest.cs | 2 +- .../Requests/Games/SendGameRequest.cs | 2 +- .../Requests/Games/SetGameScoreRequest.cs | 2 +- .../Games/SetInlineGameScoreRequest.cs | 2 +- .../Getting Updates/SetWebhookRequest.cs | 2 +- .../Inline Mode/AnswerInlineQueryRequest.cs | 2 +- .../Inline Mode/AnswerWebAppQueryRequest.cs | 2 +- .../Requests/ParameterlessRequest.cs | 6 ++--- .../Payments/CreateInvoiceLinkRequest.cs | 2 +- .../Requests/Payments/SendInvoiceRequest.cs | 2 +- .../Stickers/AddStickerToSetRequest.cs | 2 +- .../Stickers/CreateNewStickerSetRequest.cs | 2 +- .../Stickers/DeleteStickerFromSetRequest.cs | 5 ++-- .../Stickers/DeleteStickerSetRequest.cs | 3 ++- .../Stickers/GetCustomEmojiStickersRequest.cs | 2 +- .../Requests/Stickers/GetStickerSetRequest.cs | 5 ++-- .../Requests/Stickers/SendStickerRequest.cs | 2 +- ...etCustomEmojiStickerSetThumbnailRequest.cs | 3 ++- .../Stickers/SetStickerEmojiListRequest.cs | 3 ++- .../Stickers/SetStickerKeywordsRequest.cs | 3 ++- .../Stickers/SetStickerMaskPositionRequest.cs | 3 ++- .../SetStickerPositionInSetRequest.cs | 5 ++-- .../Stickers/SetStickerSetThumbnailRequest.cs | 2 +- .../Stickers/SetStickerSetTitleRequest.cs | 3 ++- .../Stickers/UploadStickerFileRequest.cs | 2 +- .../Updating messages/DeleteMessageRequest.cs | 2 +- .../DeleteMessagesRequest.cs | 2 +- .../EditInlineMessageCaptionRequest.cs | 2 +- .../EditInlineMessageMediaRequest.cs | 2 +- .../EditInlineMessageReplyMarkupRequest.cs | 2 +- .../EditInlineMessageTextRequest.cs | 2 +- .../EditMessageCaptionRequest.cs | 2 +- .../EditMessageMediaRequest.cs | 2 +- .../EditMessageReplyMarkupRequest.cs | 2 +- .../EditMessageTextRequest.cs | 2 +- .../Updating messages/StopPollRequest.cs | 2 +- .../InlineQueryResult/InlineQueryResult.cs | 2 +- .../InlineQueryResultArticle.cs | 2 +- .../InlineQueryResultAudio.cs | 2 +- .../InlineQueryResultCachedAudio.cs | 2 +- .../InlineQueryResultCachedDocument.cs | 2 +- .../InlineQueryResultCachedGif.cs | 2 +- .../InlineQueryResultCachedMpeg4Gif.cs | 2 +- .../InlineQueryResultCachedPhoto.cs | 2 +- .../InlineQueryResultCachedSticker.cs | 2 +- .../InlineQueryResultCachedVideo.cs | 2 +- .../InlineQueryResultCachedVoice.cs | 2 +- .../InlineQueryResultContact.cs | 2 +- .../InlineQueryResultDocument.cs | 2 +- .../InlineQueryResultGame.cs | 2 +- .../InlineQueryResult/InlineQueryResultGif.cs | 2 +- .../InlineQueryResultLocation.cs | 2 +- .../InlineQueryResultMpeg4Gif.cs | 2 +- .../InlineQueryResultPhoto.cs | 2 +- .../InlineQueryResultVenue.cs | 2 +- .../InlineQueryResultVideo.cs | 2 +- .../InlineQueryResultVoice.cs | 2 +- .../InputContactMessageContent.cs | 2 +- .../InputInvoiceMessageContent.cs | 2 +- .../InputLocationMessageContent.cs | 2 +- .../InputTextMessageContent.cs | 2 +- .../InputVenueMessageContent.cs | 2 +- .../Types/InputFiles/InputMedia/InputMedia.cs | 2 +- .../InputMedia/InputMediaAnimation.cs | 2 +- .../InputFiles/InputMedia/InputMediaAudio.cs | 2 +- .../InputMedia/InputMediaDocument.cs | 2 +- .../InputFiles/InputMedia/InputMediaPhoto.cs | 2 +- .../InputFiles/InputMedia/InputMediaVideo.cs | 2 +- .../Framework/UpdateReceiver.cs | 26 ++++++++++--------- 138 files changed, 162 insertions(+), 157 deletions(-) diff --git a/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs b/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs index 55fb0d100..ed41d35f0 100644 --- a/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/AnswerCallbackQueryRequest.cs @@ -66,7 +66,7 @@ public AnswerCallbackQueryRequest() : base("answerCallbackQuery") { } /// /// Unique identifier for the query to be answered [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public AnswerCallbackQueryRequest(string callbackQueryId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs index 0fe3d091c..ac5051f9b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Commands/SetMyCommandsRequest.cs @@ -38,7 +38,7 @@ public class SetMyCommandsRequest : RequestBase /// /// A list of bot commands to be set [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetMyCommandsRequest(IEnumerable commands) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs b/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs index b9675c39b..c062fd337 100644 --- a/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Get Files/GetFileRequest.cs @@ -31,7 +31,7 @@ public class GetFileRequest : RequestBase /// /// File identifier to get info about [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetFileRequest(string fileId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs b/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs index e3446c2bc..b4591778b 100644 --- a/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Get Files/GetUserProfilePhotosRequest.cs @@ -32,7 +32,7 @@ public class GetUserProfilePhotosRequest : RequestBase, IUser /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetUserProfilePhotosRequest(long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs index 5eb9aba40..62dce8505 100644 --- a/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/GetUserChatBoostsRequest.cs @@ -38,7 +38,7 @@ public GetUserChatBoostsRequest() /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetUserChatBoostsRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs index ce865fe8c..88ee3ec09 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatMemberRequest.cs @@ -48,7 +48,7 @@ public class BanChatMemberRequest : RequestBase, IChatTargetable, IUserTar /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public BanChatMemberRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs index d959060dc..67cc0c9da 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/BanChatSenderChatRequest.cs @@ -42,7 +42,7 @@ public class BanChatSenderChatRequest : RequestBase, IChatTargetable /// Unique identifier of the target sender chat /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public BanChatSenderChatRequest(ChatId chatId, long senderChatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs index 7213b3fc6..a061a24a8 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ApproveChatJoinRequest.cs @@ -30,7 +30,7 @@ public class ApproveChatJoinRequest : RequestBase, IChatTargetable, IUserT /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ApproveChatJoinRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs index 3d543b1fb..9babf9bb3 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/CreateChatInviteLinkRequest.cs @@ -52,7 +52,7 @@ public class CreateChatInviteLinkRequest : RequestBase, IChatTar /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CreateChatInviteLinkRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs index f7636cb70..05d848040 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/DeclineChatJoinRequest.cs @@ -30,7 +30,7 @@ public class DeclineChatJoinRequest : RequestBase, IChatTargetable, IUserT /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeclineChatJoinRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs index c5a48f6f0..54cba67fc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/EditChatInviteLinkRequest.cs @@ -58,7 +58,7 @@ public class EditChatInviteLinkRequest : RequestBase, IChatTarge /// /// The invite link to edit [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditChatInviteLinkRequest(ChatId chatId, string inviteLink) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs index 96fda6433..ff7881197 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/ExportChatInviteLinkRequest.cs @@ -23,7 +23,7 @@ public class ExportChatInviteLinkRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ExportChatInviteLinkRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs index 12a4b0e28..5d1fe0222 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Chat Invite Link/RevokeChatInviteLinkRequest.cs @@ -31,7 +31,7 @@ public class RevokeChatInviteLinkRequest : RequestBase, IChatTar /// /// The invite link to revoke [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public RevokeChatInviteLinkRequest(ChatId chatId, string inviteLink) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs index 1f8de0d8a..0a147a893 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseForumTopicRequest.cs @@ -28,7 +28,7 @@ public class CloseForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CloseForumTopicRequest(ChatId chatId, int messageThreadId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs index 142c4927f..87c6825ef 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CloseGeneralForumTopicRequest.cs @@ -21,7 +21,7 @@ public class CloseGeneralForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CloseGeneralForumTopicRequest(ChatId chatId) : this() => ChatId = chatId; diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs index dffe80c32..5fd3dd2fd 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/CreateForumTopicRequest.cs @@ -43,7 +43,7 @@ public class CreateForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// Topic name [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CreateForumTopicRequest(ChatId chatId, string name) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs index d5b553ea0..2a8325685 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatPhotoRequest.cs @@ -23,7 +23,7 @@ public class DeleteChatPhotoRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteChatPhotoRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs index 7ec87c121..ab028e5d5 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteChatStickerSetRequest.cs @@ -24,7 +24,7 @@ public class DeleteChatStickerSetRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteChatStickerSetRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs index 7f03e57d9..4cb60a1b7 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/DeleteForumTopicRequest.cs @@ -28,7 +28,7 @@ public class DeleteForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteForumTopicRequest(ChatId chatId, int messageThreadId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs index 405f95b34..b02c2f0a0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditForumTopicRequest.cs @@ -42,7 +42,7 @@ public class EditForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditForumTopicRequest(ChatId chatId, int messageThreadId) : this() => (ChatId, MessageThreadId) = (chatId, messageThreadId); diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs index 67aca45c6..8844d0a9e 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/EditGeneralForumTopicRequest.cs @@ -28,7 +28,7 @@ public class EditGeneralForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// New topic name, 1-128 characters [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditGeneralForumTopicRequest(ChatId chatId, string name) : this() => (ChatId, Name) = (chatId, name); diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs index 43b55eac5..16d2bb42d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatAdministratorsRequest.cs @@ -25,7 +25,7 @@ public class GetChatAdministratorsRequest : RequestBase, IChatTarg /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetChatAdministratorsRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs index 9963e88f3..de4320675 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberCountRequest.cs @@ -22,7 +22,7 @@ public class GetChatMemberCountRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetChatMemberCountRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs index 7984c146b..f4bdd3672 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatMemberRequest.cs @@ -28,7 +28,7 @@ public class GetChatMemberRequest : RequestBase, IChatTargetable, IU /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetChatMemberRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs index ba65e0c8d..3b625d32d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/Get Chat/GetChatRequest.cs @@ -26,7 +26,7 @@ public class GetChatRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetChatRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs index 253288b8b..bc951440e 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/HideGeneralForumTopicRequest.cs @@ -21,7 +21,7 @@ public class HideGeneralForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public HideGeneralForumTopicRequest(ChatId chatId) : this() => ChatId = chatId; diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs index 02ac77e5f..f2c520df4 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/LeaveChatRequest.cs @@ -22,7 +22,7 @@ public class LeaveChatRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public LeaveChatRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs index 4ee7a28a9..671039a7a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PinChatMessageRequest.cs @@ -36,7 +36,7 @@ public class PinChatMessageRequest : RequestBase, IChatTargetable /// /// Identifier of a message to pin [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public PinChatMessageRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs index ec045a581..74b26a91a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/PromoteChatMemberRequest.cs @@ -123,7 +123,7 @@ public class PromoteChatMemberRequest : RequestBase, IChatTargetable, IUse /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public PromoteChatMemberRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs index b1d1959fe..5443af88d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenForumTopicRequest.cs @@ -28,7 +28,7 @@ public class ReopenForumTopicRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ReopenForumTopicRequest(ChatId chatId, int messageThreadId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs index 2fb8bc11f..f9280fe66 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/ReopenGeneralForumTopicRequest.cs @@ -21,7 +21,7 @@ public class ReopenGeneralForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ReopenGeneralForumTopicRequest(ChatId chatId) : this() => ChatId = chatId; diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs index 21cf7f0f0..43e99c6e5 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/RestrictChatMemberRequest.cs @@ -58,7 +58,7 @@ public class RestrictChatMemberRequest : RequestBase, IChatTargetable, IUs /// Unique identifier of the target user /// New user permissions [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public RestrictChatMemberRequest(ChatId chatId, long userId, ChatPermissions permissions) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs index 0e374ab15..9ed2f9284 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatAdministratorCustomTitleRequest.cs @@ -36,7 +36,7 @@ public class SetChatAdministratorCustomTitleRequest : RequestBase, IChatTa /// New custom title for the administrator; 0-16 characters, emoji are not allowed /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatAdministratorCustomTitleRequest(ChatId chatId, long userId, string customTitle) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs index cce0e3756..234018482 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatDescriptionRequest.cs @@ -30,7 +30,7 @@ public class SetChatDescriptionRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatDescriptionRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs index 3c9fdaebb..556fb4307 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPermissionsRequest.cs @@ -43,7 +43,7 @@ public class SetChatPermissionsRequest : RequestBase, IChatTargetable /// /// New default chat permissions [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatPermissionsRequest(ChatId chatId, ChatPermissions permissions) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs index 556416fe6..44170308e 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatPhotoRequest.cs @@ -31,7 +31,7 @@ public class SetChatPhotoRequest : FileRequestBase, IChatTargetable /// /// New chat photo, uploaded using multipart/form-data [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatPhotoRequest(ChatId chatId, InputFileStream photo) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs index 6b90e6faf..2c3b9b0cc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatStickerSetRequest.cs @@ -31,7 +31,7 @@ public class SetChatStickerSetRequest : RequestBase, IChatTargetable /// /// Name of the sticker set to be set as the group sticker set [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatStickerSetRequest(ChatId chatId, string stickerSetName) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs index acc8cd4dd..7eeca20d0 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/SetChatTitleRequest.cs @@ -30,7 +30,7 @@ public class SetChatTitleRequest : RequestBase, IChatTargetable /// /// New chat title, 1-255 characters [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetChatTitleRequest(ChatId chatId, string title) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs index 66f33eb25..6bae92753 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatMemberRequest.cs @@ -37,7 +37,7 @@ public class UnbanChatMemberRequest : RequestBase, IChatTargetable, IUserT /// /// Unique identifier of the target user [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnbanChatMemberRequest(ChatId chatId, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs index ef8a77891..5406a2cba 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnbanChatSenderChatRequest.cs @@ -32,7 +32,7 @@ public class UnbanChatSenderChatRequest : RequestBase, IChatTargetable /// Unique identifier of the target sender chat /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnbanChatSenderChatRequest(ChatId chatId, long senderChatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs index e7a27c115..52cfbb097 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnhideGeneralForumTopicRequest.cs @@ -21,7 +21,7 @@ public class UnhideGeneralForumTopicRequest : RequestBase, IChatTargetable /// /// Unique identifier for the target chat or username of the target supergroup [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnhideGeneralForumTopicRequest(ChatId chatId) : this() => ChatId = chatId; diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs index ec62c121c..80374dfdb 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllChatMessagesRequest.cs @@ -25,7 +25,7 @@ public class UnpinAllChatMessagesRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnpinAllChatMessagesRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs index 38d373594..e4de3973a 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinAllForumTopicMessagesRequest.cs @@ -28,7 +28,7 @@ public class UnpinAllForumTopicMessagesRequest : RequestBase, IChatTargeta /// Unique identifier for the target chat or username of the target supergroup /// Unique identifier for the target message thread of the forum topic [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnpinAllForumTopicMessagesRequest(ChatId chatId, int messageThreadId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs index 9a1611be3..663dbbb09 100644 --- a/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Manage Chat/UnpinChatMessageRequest.cs @@ -32,7 +32,7 @@ public class UnpinChatMessageRequest : RequestBase, IChatTargetable /// (in the format @channelusername) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UnpinChatMessageRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs index 67dfa793b..85264a70e 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessageRequest.cs @@ -88,7 +88,7 @@ public class CopyMessageRequest : RequestBase, IChatTargetable /// Message identifier in the chat specified in /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CopyMessageRequest(ChatId chatId, ChatId fromChatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs index 36346ba5b..38e2180ee 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/CopyMessagesRequest.cs @@ -73,7 +73,7 @@ public class CopyMessagesRequest : RequestBase, IChatTargetable /// The identifiers must be specified in a strictly increasing order. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CopyMessagesRequest(ChatId chatId, ChatId fromChatId, int[] messageIds) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs index 59fa50401..b3fe4ee2d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessageRequest.cs @@ -58,7 +58,7 @@ public class ForwardMessageRequest : RequestBase, IChatTargetable /// Message identifier in the chat specified in /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ForwardMessageRequest(ChatId chatId, ChatId fromChatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs index f6a6a7c5c..74fb120f2 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/ForwardMessagesRequest.cs @@ -65,7 +65,7 @@ public class ForwardMessagesRequest : RequestBase, IChatTargetable /// The identifiers must be specified in a strictly increasing order. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public ForwardMessagesRequest(ChatId chatId, ChatId fromChatId, IEnumerable messageIds) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs index 862c83db6..147af9a5f 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditInlineMessageLiveLocationRequest.cs @@ -58,7 +58,7 @@ public class EditInlineMessageLiveLocationRequest : RequestBase /// Latitude of new location /// Longitude of new location [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditInlineMessageLiveLocationRequest(string inlineMessageId, double latitude, double longitude) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs index ace9fe06c..9ad752e96 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/EditMessageLiveLocationRequest.cs @@ -69,7 +69,7 @@ public class EditMessageLiveLocationRequest : RequestBase, IChatTargeta /// Latitude of new location /// Longitude of new location [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditMessageLiveLocationRequest(ChatId chatId, int messageId, double latitude, double longitude) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs index 638ac2300..c0733db4d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendLocationRequest.cs @@ -86,7 +86,7 @@ public class SendLocationRequest : RequestBase, IChatTargetable /// Latitude of the location /// Longitude of the location [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendLocationRequest(ChatId chatId, double latitude, double longitude) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs index 30df065a4..0558c9898 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/SendVenueRequest.cs @@ -98,7 +98,7 @@ public class SendVenueRequest : RequestBase, IChatTargetable /// Name of the venue /// Address of the venue [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendVenueRequest( ChatId chatId, double latitude, diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs index 8262b6a8c..8e0a1e6ad 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopInlineMessageLiveLocationRequest.cs @@ -24,7 +24,7 @@ public class StopInlineMessageLiveLocationRequest : RequestBase /// /// Identifier of the inline message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public StopInlineMessageLiveLocationRequest(string inlineMessageId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs index 85055bc45..ed60f59f5 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/Location/StopMessageLiveLocationRequest.cs @@ -35,7 +35,7 @@ public class StopMessageLiveLocationRequest : RequestBase, IChatTargeta /// /// Identifier of the sent message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public StopMessageLiveLocationRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs index 71f4182cd..f3c7f81c3 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAnimationRequest.cs @@ -106,7 +106,7 @@ public class SendAnimationRequest : FileRequestBase, IChatTargetable /// get an animation from the Internet, or upload a new animation using multipart/form-data /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendAnimationRequest(ChatId chatId, InputFile animation) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs index 99845b107..5b4b09536 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendAudioRequest.cs @@ -100,7 +100,7 @@ public class SendAudioRequest : FileRequestBase, IChatTargetable /// Telegram to get an audio file from the Internet, or upload a new one using multipart/form-data /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendAudioRequest(ChatId chatId, InputFile audio) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs index 603f16cc6..ba251bd36 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendChatActionRequest.cs @@ -59,7 +59,7 @@ public class SendChatActionRequest : RequestBase, IChatTargetable /// Type of action to broadcast. Choose one, depending on what the user is about to receive /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendChatActionRequest(ChatId chatId, ChatAction action) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs index 1ac981e38..e4835d9b6 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendContactRequest.cs @@ -70,7 +70,7 @@ public class SendContactRequest : RequestBase, IChatTargetable /// Contact's phone number /// Contact's first name [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendContactRequest(ChatId chatId, string phoneNumber, string firstName) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs index 5f41eb5b7..7203cd83d 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDiceRequest.cs @@ -53,7 +53,7 @@ public class SendDiceRequest : RequestBase, IChatTargetable /// Unique identifier for the target chat or username of the target channel /// (in the format @channelusername) [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendDiceRequest(ChatId chatId) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs index 3a7d9a36c..b9ac628a4 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendDocumentRequest.cs @@ -88,7 +88,7 @@ public class SendDocumentRequest : FileRequestBase, IChatTargetable /// to get a file from the Internet, or upload a new one using multipart/form-data /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendDocumentRequest(ChatId chatId, InputFile document) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs index 59bf897a9..f51872725 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMediaGroupRequest.cs @@ -52,7 +52,7 @@ public class SendMediaGroupRequest : FileRequestBase, IChatTargetable /// /// An array describing messages to be sent, must include 2-10 items [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendMediaGroupRequest(ChatId chatId, IEnumerable media) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs index b080ed5e2..fdc09fbcf 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendMessageRequest.cs @@ -67,7 +67,7 @@ public class SendMessageRequest : RequestBase, IChatTargetable /// /// Text of the message to be sent, 1-4096 characters after entities parsing [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendMessageRequest(ChatId chatId, string text) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs index ae5b5e628..a83ba5014 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPhotoRequest.cs @@ -84,7 +84,7 @@ public class SendPhotoRequest : FileRequestBase, IChatTargetable /// must be at most 10 MB in size. The photo's width and height must not exceed 10000 in total. /// Width and height ratio must be at most 20 [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendPhotoRequest(ChatId chatId, InputFile photo) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs index 95ce4f7a5..4035913e8 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendPollRequest.cs @@ -129,7 +129,7 @@ public class SendPollRequest : RequestBase, IChatTargetable /// Poll question, 1-300 characters /// A list of answer options, 2-10 strings 1-100 characters each [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendPollRequest(ChatId chatId, string question, IEnumerable options) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs index 35a213eaa..a13af1c65 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoNoteRequest.cs @@ -77,7 +77,7 @@ public class SendVideoNoteRequest : FileRequestBase, IChatTargetable /// multipart/form-data. Sending video notes by a URL is currently unsupported /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendVideoNoteRequest(ChatId chatId, InputFile videoNote) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs index 1e9afc430..3d4a65786 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVideoRequest.cs @@ -112,7 +112,7 @@ public class SendVideoRequest : FileRequestBase, IChatTargetable /// get a video from the Internet, or upload a new video using multipart/form-data /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendVideoRequest(ChatId chatId, InputFile video) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs index 109a1db5a..8c8ce6f85 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SendVoiceRequest.cs @@ -84,7 +84,7 @@ public class SendVoiceRequest : FileRequestBase, IChatTargetable /// to get a file from the Internet, or upload a new one using multipart/form-data /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendVoiceRequest(ChatId chatId, InputFile voice) : this() { diff --git a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs index 46293d99f..7ee9704bc 100644 --- a/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs +++ b/src/Telegram.Bot/Requests/Available methods/Messages/SetMessageReactionRequest.cs @@ -51,7 +51,7 @@ public class SetMessageReactionRequest : RequestBase, /// is set to the first non-deleted message in the group instead. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetMessageReactionRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs b/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs index f354247d4..f4c65e5ad 100644 --- a/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs +++ b/src/Telegram.Bot/Requests/Games/GetGameHighScoresRequest.cs @@ -43,7 +43,7 @@ public class GetGameHighScoresRequest : RequestBase, IUserTarge /// Unique identifier for the target chat /// Identifier of the sent message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetGameHighScoresRequest(long userId, long chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs b/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs index b01ecb26f..1e7536aa9 100644 --- a/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs +++ b/src/Telegram.Bot/Requests/Games/GetInlineGameHighScoresRequest.cs @@ -31,7 +31,7 @@ public class GetInlineGameHighScoresRequest : RequestBase, IUse /// User identifier /// Identifier of the inline message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetInlineGameHighScoresRequest(long userId, string inlineMessageId) : this() { diff --git a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs index 140a7febe..abb390577 100644 --- a/src/Telegram.Bot/Requests/Games/SendGameRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SendGameRequest.cs @@ -58,7 +58,7 @@ public class SendGameRequest : RequestBase, IChatTargetable /// @BotFather /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendGameRequest(long chatId, string gameShortName) : this() { diff --git a/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs b/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs index 83eeed2b3..0e0c9f20a 100644 --- a/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SetGameScoreRequest.cs @@ -59,7 +59,7 @@ public class SetGameScoreRequest : RequestBase, IUserTargetable, IChatT /// Unique identifier for the target chat /// Identifier of the sent message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetGameScoreRequest(long userId, int score, long chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs b/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs index 680908533..1796949db 100644 --- a/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs +++ b/src/Telegram.Bot/Requests/Games/SetInlineGameScoreRequest.cs @@ -47,7 +47,7 @@ public class SetInlineGameScoreRequest : RequestBase, IUserTargetable /// New score, must be non-negative /// Identifier of the inline message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetInlineGameScoreRequest(long userId, int score, string inlineMessageId) : this() { diff --git a/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs b/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs index a5bad7293..aa52c998f 100644 --- a/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs +++ b/src/Telegram.Bot/Requests/Getting Updates/SetWebhookRequest.cs @@ -102,7 +102,7 @@ public class SetWebhookRequest : FileRequestBase /// HTTPS url to send updates to. Use an empty string to remove webhook integration /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetWebhookRequest(string url) : base("setWebhook") => Url = url; diff --git a/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs b/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs index 36372467f..4b2265397 100644 --- a/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Inline Mode/AnswerInlineQueryRequest.cs @@ -60,7 +60,7 @@ public class AnswerInlineQueryRequest : RequestBase /// Unique identifier for the answered query /// An array of results for the inline query [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public AnswerInlineQueryRequest(string inlineQueryId, IEnumerable results) : this() { diff --git a/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs b/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs index 09f80532d..320cb4457 100644 --- a/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Inline Mode/AnswerWebAppQueryRequest.cs @@ -30,7 +30,7 @@ public class AnswerWebAppQueryRequest : RequestBase /// Unique identifier for the query to be answered /// An object describing the message to be sent [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public AnswerWebAppQueryRequest(string webAppQueryId, InlineQueryResult result) : this() { diff --git a/src/Telegram.Bot/Requests/ParameterlessRequest.cs b/src/Telegram.Bot/Requests/ParameterlessRequest.cs index 1c9cd5fd7..e0a2bff02 100644 --- a/src/Telegram.Bot/Requests/ParameterlessRequest.cs +++ b/src/Telegram.Bot/Requests/ParameterlessRequest.cs @@ -7,13 +7,13 @@ namespace Telegram.Bot.Requests; /// /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public class ParameterlessRequest : RequestBase +public abstract class ParameterlessRequest : RequestBase { /// /// Initializes an instance of /// /// Name of request method - public ParameterlessRequest(string methodName) + protected ParameterlessRequest(string methodName) : base(methodName) { } @@ -22,7 +22,7 @@ public ParameterlessRequest(string methodName) /// /// Name of request method /// HTTP request method - public ParameterlessRequest(string methodName, HttpMethod method) + protected ParameterlessRequest(string methodName, HttpMethod method) : base(methodName, method) { } diff --git a/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs b/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs index 5d71ed0ae..5252145a1 100644 --- a/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/CreateInvoiceLinkRequest.cs @@ -162,7 +162,7 @@ public class CreateInvoiceLinkRequest : RequestBase /// delivery tax, bonus, etc.) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CreateInvoiceLinkRequest( string title, string description, diff --git a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs index e0d6c1cc5..d681cf4b0 100644 --- a/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/SendInvoiceRequest.cs @@ -210,7 +210,7 @@ public class SendInvoiceRequest : RequestBase, IChatTargetable /// delivery tax, bonus, etc.) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendInvoiceRequest( long chatId, string title, diff --git a/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs index 5db8dacec..e7e8e12cc 100644 --- a/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/AddStickerToSetRequest.cs @@ -55,7 +55,7 @@ public class AddStickerToSetRequest : FileRequestBase, IUserTargetable /// If exactly the same sticker had already been added to the set, then the set isn't changed. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public AddStickerToSetRequest( long userId, string name, diff --git a/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs index f9f4f9fb7..629312d5f 100644 --- a/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/CreateNewStickerSetRequest.cs @@ -85,7 +85,7 @@ public class CreateNewStickerSetRequest : FileRequestBase, IUserTargetable /// Format of stickers in the set. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public CreateNewStickerSetRequest( long userId, string name, diff --git a/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs index 0eca11442..7082e5f42 100644 --- a/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/DeleteStickerFromSetRequest.cs @@ -1,7 +1,6 @@ -// ReSharper disable once CheckNamespace - using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -23,7 +22,7 @@ public class DeleteStickerFromSetRequest : RequestBase /// File identifier of the sticker /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteStickerFromSetRequest(InputFileId sticker) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs index ba5ebc150..d7d467e26 100644 --- a/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/DeleteStickerSetRequest.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -22,7 +23,7 @@ namespace Telegram.Bot.Requests; /// Sticker set name /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteStickerSetRequest(string name) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs b/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs index 97a3e87d9..9a339ba6e 100644 --- a/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/GetCustomEmojiStickersRequest.cs @@ -24,7 +24,7 @@ public class GetCustomEmojiStickersRequest : RequestBase /// List of custom emoji identifiers. At most 200 custom emoji identifiers can be specified. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetCustomEmojiStickersRequest(IEnumerable customEmojiIds) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs index c27016e22..0715a00d9 100644 --- a/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/GetStickerSetRequest.cs @@ -1,7 +1,6 @@ -// ReSharper disable once CheckNamespace - using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -21,7 +20,7 @@ public class GetStickerSetRequest : RequestBase /// /// Name of the sticker set [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public GetStickerSetRequest(string name) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs index f4948174f..12f581792 100644 --- a/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SendStickerRequest.cs @@ -72,7 +72,7 @@ public class SendStickerRequest : FileRequestBase, IChatTargetable /// Animated stickers can't be sent via an HTTP URL. /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SendStickerRequest(ChatId chatId, InputFile sticker) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs index f525cfb66..c4b0f983d 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetCustomEmojiStickerSetThumbnailRequest.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -29,7 +30,7 @@ public class SetCustomEmojiStickerSetThumbnailRequest : RequestBase /// Sticker set name /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetCustomEmojiStickerSetThumbnailRequest(string name) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs index aed873477..a063aabcd 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerEmojiListRequest.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -33,7 +34,7 @@ public class SetStickerEmojiListRequest : RequestBase /// A JSON-serialized list of 1-20 emoji associated with the sticker /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerEmojiListRequest(InputFileId sticker, IEnumerable emojiList) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs index a9e49a6e3..222c680b2 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerKeywordsRequest.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -31,7 +32,7 @@ public class SetStickerKeywordsRequest : RequestBase /// File identifier of the sticker /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerKeywordsRequest(InputFileId sticker) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs index 8895e77c9..651c12fd9 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerMaskPositionRequest.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -31,7 +32,7 @@ public class SetStickerMaskPositionRequest : RequestBase /// File identifier of the sticker /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerMaskPositionRequest(InputFileId sticker) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs index 2e192afe1..d6ea2baaa 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerPositionInSetRequest.cs @@ -1,7 +1,6 @@ -// ReSharper disable once CheckNamespace - using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -31,7 +30,7 @@ public class SetStickerPositionInSetRequest : RequestBase /// /// New sticker position in the set, zero-based [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerPositionInSetRequest(InputFileId sticker, int position) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs index c10074193..6945d85bc 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerSetThumbnailRequest.cs @@ -43,7 +43,7 @@ public class SetStickerSetThumbnailRequest : FileRequestBase, IUserTargeta /// Sticker set name /// User identifier of the sticker set owner [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerSetThumbnailRequest(string name, long userId) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs b/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs index af9ce734b..3f970c79f 100644 --- a/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/SetStickerSetTitleRequest.cs @@ -1,5 +1,6 @@ using System.Diagnostics.CodeAnalysis; +// ReSharper disable once CheckNamespace namespace Telegram.Bot.Requests; /// @@ -31,7 +32,7 @@ public class SetStickerSetTitleRequest : RequestBase /// Sticker set title, 1-64 characters /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public SetStickerSetTitleRequest(string name, string title) : this() { diff --git a/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs b/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs index 233dbf0a4..1e31a0eb4 100644 --- a/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs +++ b/src/Telegram.Bot/Requests/Stickers/UploadStickerFileRequest.cs @@ -45,7 +45,7 @@ public class UploadStickerFileRequest : FileRequestBase, IUserTargetable /// Format of the sticker /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public UploadStickerFileRequest(long userId, InputFileStream sticker, StickerFormat stickerFormat) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs b/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs index eb152327b..fe7780bee 100644 --- a/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/DeleteMessageRequest.cs @@ -42,7 +42,7 @@ public class DeleteMessageRequest : RequestBase, IChatTargetable /// /// Identifier of the message to delete [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteMessageRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs index 097944b9d..5f4e67797 100644 --- a/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/DeleteMessagesRequest.cs @@ -36,7 +36,7 @@ public class DeleteMessagesRequest : RequestBase, IChatTargetable /// for limitations on which messages can be deleted /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public DeleteMessagesRequest(ChatId chatId, IEnumerable messageIds) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs index a8ff5a1dc..660291d1a 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageCaptionRequest.cs @@ -40,7 +40,7 @@ public class EditInlineMessageCaptionRequest : RequestBase /// /// Identifier of the inline message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditInlineMessageCaptionRequest(string inlineMessageId) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs index bc88982ec..e918dd761 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageMediaRequest.cs @@ -35,7 +35,7 @@ public class EditInlineMessageMediaRequest : RequestBase /// Identifier of the inline message /// A new media content of the message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditInlineMessageMediaRequest(string inlineMessageId, InputMedia media) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs index fdd3147f6..3d6d10f96 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageReplyMarkupRequest.cs @@ -24,7 +24,7 @@ public class EditInlineMessageReplyMarkupRequest : RequestBase /// /// Identifier of the inline message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditInlineMessageReplyMarkupRequest(string inlineMessageId) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs index 42f6d7ea0..727dd7bcc 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditInlineMessageTextRequest.cs @@ -47,7 +47,7 @@ public class EditInlineMessageTextRequest : RequestBase /// Identifier of the inline message /// New text of the message, 1-4096 characters after entities parsing [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditInlineMessageTextRequest(string inlineMessageId, string text) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs index aaf5df188..a0ad5b8f3 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageCaptionRequest.cs @@ -49,7 +49,7 @@ public class EditMessageCaptionRequest : RequestBase, IChatTargetable /// /// Identifier of the message to edit [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditMessageCaptionRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs index 87794f897..ae3bc83cd 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageMediaRequest.cs @@ -48,7 +48,7 @@ public class EditMessageMediaRequest : FileRequestBase, IChatTargetable /// Identifier of the message to edit /// A new media content of the message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditMessageMediaRequest(ChatId chatId, int messageId, InputMedia media) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs index 3a8d06956..a8c7a7158 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageReplyMarkupRequest.cs @@ -35,7 +35,7 @@ public class EditMessageReplyMarkupRequest : RequestBase, IChatTargetab /// /// Identifier of the message to edit [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditMessageReplyMarkupRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs index 0dd1eaabd..cab8edc66 100644 --- a/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/EditMessageTextRequest.cs @@ -57,7 +57,7 @@ public class EditMessageTextRequest : RequestBase, IChatTargetable /// Identifier of the message to edit /// New text of the message, 1-4096 characters after entities parsing [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public EditMessageTextRequest(ChatId chatId, int messageId, string text) : this() { diff --git a/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs b/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs index a26319044..0c9dbe1f0 100644 --- a/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs +++ b/src/Telegram.Bot/Requests/Updating messages/StopPollRequest.cs @@ -36,7 +36,7 @@ public class StopPollRequest : RequestBase, IChatTargetable /// /// Identifier of the original message with the poll [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public StopPollRequest(ChatId chatId, int messageId) : this() { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs index 7e3373c51..2e9a26ef2 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResult.cs @@ -33,7 +33,7 @@ public abstract class InlineQueryResult /// /// Unique identifier for this result, 1-64 Bytes [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] protected InlineQueryResult(string id) => Id = id; /// diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs index 4b36590e8..abfaa2aa0 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultArticle.cs @@ -64,7 +64,7 @@ public class InlineQueryResultArticle : InlineQueryResult /// Title of the result /// Content of the message to be sent [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultArticle(string id, string title, InputMessageContent inputMessageContent) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs index 580746864..bbfde1677 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultAudio.cs @@ -65,7 +65,7 @@ public class InlineQueryResultAudio : InlineQueryResult /// A valid URL for the audio file /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultAudio(string id, string audioUrl, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs index a7ccdab6f..d7e31cfb9 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedAudio.cs @@ -47,7 +47,7 @@ public class InlineQueryResultCachedAudio : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the audio file [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedAudio(string id, string audioFileId) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs index 190aaee85..ebdfe0f33 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedDocument.cs @@ -60,7 +60,7 @@ public class InlineQueryResultCachedDocument : InlineQueryResult /// A valid file identifier for the file /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedDocument(string id, string documentFileId, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs index c19dba568..8b602833f 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedGif.cs @@ -53,7 +53,7 @@ public class InlineQueryResultCachedGif : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the GIF file [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedGif(string id, string gifFileId) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs index 36ecff411..c7ab246da 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedMpeg4Gif.cs @@ -54,7 +54,7 @@ public class InlineQueryResultCachedMpeg4Gif : InlineQueryResult /// Unique identifier of this result /// A valid file identifier for the MP4 file [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedMpeg4Gif(string id, string mpeg4FileId) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs index 0901729a4..6ef88c4ae 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedPhoto.cs @@ -59,7 +59,7 @@ public class InlineQueryResultCachedPhoto : InlineQueryResult /// Unique identifier of this result /// A valid file identifier of the photo [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedPhoto(string id, string photoFileId) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs index 740d56572..597f46d24 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedSticker.cs @@ -34,7 +34,7 @@ public class InlineQueryResultCachedSticker : InlineQueryResult /// Unique identifier of this result /// A valid file identifier of the sticker [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedSticker(string id, string stickerFileId) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs index f1ba4ece7..aa960d185 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVideo.cs @@ -60,7 +60,7 @@ public class InlineQueryResultCachedVideo : InlineQueryResult /// A valid file identifier for the video file /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedVideo(string id, string videoFileId, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs index be4fa3cce..feaeb03a7 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultCached/InlineQueryResultCachedVoice.cs @@ -54,7 +54,7 @@ public class InlineQueryResultCachedVoice : InlineQueryResult /// A valid file identifier for the voice message /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultCachedVoice(string id, string fileId, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs index 554bd1cbf..fa4ec2e70 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultContact.cs @@ -64,7 +64,7 @@ public class InlineQueryResultContact : InlineQueryResult /// Contact's phone number /// Contact's first name [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultContact(string id, string phoneNumber, string firstName) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs index 5b18e2164..cc09a34d1 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultDocument.cs @@ -81,7 +81,7 @@ public class InlineQueryResultDocument : InlineQueryResult /// Mime type of the content of the file, either “application/pdf” or “application/zip” /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultDocument(string id, string documentUrl, string title, string mimeType) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs index 3b2d438d5..e55cf110a 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGame.cs @@ -27,7 +27,7 @@ public class InlineQueryResultGame : InlineQueryResult /// Unique identifier of this result /// Short name of the game [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultGame(string id, string gameShortName) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs index dd9849472..43116bf8d 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultGif.cs @@ -85,7 +85,7 @@ public class InlineQueryResultGif : InlineQueryResult /// Width of the GIF /// Url of the thumbnail for the result. [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultGif(string id, string gifUrl, string thumbnailUrl) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs index d60dac166..7da6fd44d 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultLocation.cs @@ -81,7 +81,7 @@ public class InlineQueryResultLocation : InlineQueryResult /// Longitude of the location in degrees /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultLocation(string id, double latitude, double longitude, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs index df315bd74..044db7a24 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultMpeg4Gif.cs @@ -85,7 +85,7 @@ public class InlineQueryResultMpeg4Gif : InlineQueryResult /// A valid URL for the MP4 file. File size must not exceed 1MB. /// Url of the thumbnail for the result. [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultMpeg4Gif(string id, string mpeg4Url, string thumbnailUrl) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs index 8993fb4d1..49b72db4a 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultPhoto.cs @@ -75,7 +75,7 @@ public class InlineQueryResultPhoto : InlineQueryResult /// A valid URL of the photo. Photo size must not exceed 5MB. /// Optional. Url of the thumbnail for the result. [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultPhoto(string id, string photoUrl, string thumbnailUrl) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs index 858c5dce1..1e127702b 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVenue.cs @@ -88,7 +88,7 @@ public class InlineQueryResultVenue : InlineQueryResult /// Title of the result /// Address of the venue [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultVenue( string id, double latitude, diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs index 0aad047b9..482bea227 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVideo.cs @@ -104,7 +104,7 @@ public class InlineQueryResultVideo : InlineQueryResult /// (e.g., a YouTube video). /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultVideo( string id, string videoUrl, diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs index 7ae68b7e6..4e8655449 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InlineQueryResult/InlineQueryResultVoice.cs @@ -60,7 +60,7 @@ public class InlineQueryResultVoice : InlineQueryResult /// A valid URL for the voice recording /// Title of the result [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InlineQueryResultVoice(string id, string voiceUrl, string title) : base(id) { diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs index 3719997fb..354d971ab 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputContactMessageContent.cs @@ -39,7 +39,7 @@ public class InputContactMessageContent : InputMessageContent /// The phone number of the contact /// The first name of the contact [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputContactMessageContent(string phoneNumber, string firstName) { PhoneNumber = phoneNumber; diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs index 49cca0b5e..ee0915a85 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputInvoiceMessageContent.cs @@ -160,7 +160,7 @@ public class InputInvoiceMessageContent : InputMessageContent /// delivery tax, bonus, etc.) /// [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputInvoiceMessageContent( string title, string description, diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs index 77e215f98..f3aa2f83a 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputLocationMessageContent.cs @@ -53,7 +53,7 @@ public class InputLocationMessageContent : InputMessageContent /// The latitude of the location /// The longitude of the location [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputLocationMessageContent(double latitude, double longitude) { Latitude = latitude; diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs index b98d4cdb9..919d2fb5b 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputTextMessageContent.cs @@ -43,7 +43,7 @@ public class InputTextMessageContent : InputMessageContent /// /// The text of the message [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputTextMessageContent(string messageText) { MessageText = messageText; diff --git a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs index b9f7086b3..3f3f86954 100644 --- a/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs +++ b/src/Telegram.Bot/Types/InlineQueryResults/InputMessageContent/InputVenueMessageContent.cs @@ -68,7 +68,7 @@ public class InputVenueMessageContent : InputMessageContent /// The latitude of the venue /// The longitude of the venue [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputVenueMessageContent(string title, string address, double latitude, double longitude) { Title = title; diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs index 4d07152a2..bae459a8b 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMedia.cs @@ -48,7 +48,7 @@ public abstract class InputMedia /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] protected InputMedia(InputFile media) => Media = media; /// diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs index 535eceb16..94cae62a5 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAnimation.cs @@ -49,7 +49,7 @@ public class InputMediaAnimation : /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputMediaAnimation(InputFile media) : base(media) { } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs index 3d84bf209..13c6ca3f7 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaAudio.cs @@ -44,7 +44,7 @@ public class InputMediaAudio : /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputMediaAudio(InputFile media) : base(media) { } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs index 7072a9f07..60ca90685 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaDocument.cs @@ -33,7 +33,7 @@ public class InputMediaDocument : /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputMediaDocument(InputFile media) : base(media) { } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs index 4781b950c..b96b707dc 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaPhoto.cs @@ -26,7 +26,7 @@ public class InputMediaPhoto : /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputMediaPhoto(InputFile media) : base(media) { } diff --git a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs index 41f832568..d77f2b2e2 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputMedia/InputMediaVideo.cs @@ -56,7 +56,7 @@ public class InputMediaVideo : /// /// File to send [SetsRequiredMembers] - [Obsolete("Use parameterless constructor with required parameters")] + [Obsolete("Use parameterless constructor with required properties")] public InputMediaVideo(InputFile media) : base(media) { } diff --git a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs index b5061fa2e..3a7138d1f 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs @@ -19,8 +19,6 @@ public enum UpdatePosition public class UpdateReceiver(ITelegramBotClient botClient, IEnumerable? allowedUsernames) { - readonly ITelegramBotClient _botClient = botClient; - public List AllowedUsernames { get; } = allowedUsernames?.ToList() ?? []; public async Task DiscardNewUpdatesAsync(CancellationToken cancellationToken = default) @@ -39,9 +37,12 @@ public async Task DiscardNewUpdatesAsync(CancellationToken cancellationToken = d while (!cancellationToken.IsCancellationRequested) { - var updates = await _botClient.GetUpdatesAsync( - offset: offset, - allowedUpdates: Enum.GetValues().Where(u => u != UpdateType.Unknown), + var updates = await botClient.GetUpdatesAsync( + new() + { + Offset = offset, + AllowedUpdates = Enum.GetValues().Where(u => u != UpdateType.Unknown) + }, cancellationToken: cancellationToken ); @@ -184,9 +185,8 @@ public async Task GetInlineQueryUpdateAsync( { await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); var updates = await GetUpdatesAsync( - predicate: u => (u.Message is { Chat.Id: var id, Type: var type } && - id == chatId && type == messageType) || - u.ChosenInlineResult is not null, + predicate: u => (u.Message is { Chat.Id: var id, Type: var type } && id == chatId && type == messageType) + || u.ChosenInlineResult is not null, cancellationToken: cancellationToken, updateTypes: [UpdateType.Message, UpdateType.ChosenInlineResult] ); @@ -211,10 +211,12 @@ async Task GetOnlyAllowedUpdatesAsync( CancellationToken cancellationToken, params UpdateType[] types) { - var updates = await _botClient.GetUpdatesAsync( - offset: offset, - timeout: 120, - allowedUpdates: types, + var updates = await botClient.GetUpdatesAsync( + new() { + Offset = offset, + Timeout = 120, + AllowedUpdates = types, + }, cancellationToken: cancellationToken ); From 8976b9ff83e2a55a8ff7db327889fb993fd657ce Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Tue, 27 Feb 2024 01:35:47 +0400 Subject: [PATCH 79/90] Use factory methods for InputFile --- src/Telegram.Bot/Converters/InputFileConverter.cs | 4 ++-- src/Telegram.Bot/Types/InputFiles/InputFile.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Telegram.Bot/Converters/InputFileConverter.cs b/src/Telegram.Bot/Converters/InputFileConverter.cs index 1ca84c50e..0a30ef462 100644 --- a/src/Telegram.Bot/Converters/InputFileConverter.cs +++ b/src/Telegram.Bot/Converters/InputFileConverter.cs @@ -32,7 +32,7 @@ public override void WriteJson(JsonWriter writer, InputFile? value, JsonSerializ } return Uri.TryCreate(value, UriKind.Absolute, out var url) - ? new InputFileUrl(url) - : new InputFileId(value); + ? InputFile.FromUri(url) + : InputFile.FromFileId(value); } } diff --git a/src/Telegram.Bot/Types/InputFiles/InputFile.cs b/src/Telegram.Bot/Types/InputFiles/InputFile.cs index 51e612a9b..b8080b472 100644 --- a/src/Telegram.Bot/Types/InputFiles/InputFile.cs +++ b/src/Telegram.Bot/Types/InputFiles/InputFile.cs @@ -26,8 +26,8 @@ public abstract class InputFile /// An instance of a class that implements public static InputFile FromString(string urlOrFileId) => Uri.TryCreate(urlOrFileId, UriKind.Absolute, out var url) - ? new InputFileUrl(url) - : new InputFileId(urlOrFileId); + ? FromUri(url) + : FromFileId(urlOrFileId); /// /// Creates an from an instance From 1605f68b3d4e2109122211a8d04b381be3ffca3d Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Tue, 27 Feb 2024 01:36:22 +0400 Subject: [PATCH 80/90] Add setters to AnswerPreCheckoutQueryRequest for error message --- .../Requests/Payments/AnswerPreCheckoutQueryRequest.cs | 2 +- .../Requests/Payments/AnswerShippingQueryRequest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs b/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs index ecebc5471..3e20680ca 100644 --- a/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/AnswerPreCheckoutQueryRequest.cs @@ -35,7 +35,7 @@ public class AnswerPreCheckoutQueryRequest : RequestBase /// Please choose a different color or garment!"). Telegram will display this message to the user. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public string? ErrorMessage { get; } + public string? ErrorMessage { get; set; } /// /// Initializes a new successful answerPreCheckoutQuery request diff --git a/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs b/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs index f54c9026d..7f973b710 100644 --- a/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs +++ b/src/Telegram.Bot/Requests/Payments/AnswerShippingQueryRequest.cs @@ -39,7 +39,7 @@ public class AnswerShippingQueryRequest : RequestBase /// is unavailable'). Telegram will display this message to the user. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] - public string? ErrorMessage { get; } + public string? ErrorMessage { get; set; } /// /// Initializes a new failing answerShippingQuery request with error message From e3beb08b64fd57ebdec4c6ed8f97873405b4d23c Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Tue, 27 Feb 2024 01:36:50 +0400 Subject: [PATCH 81/90] Migrate some integration tests to use new APIs with request classes --- .../Admin Bot/ChannelAdminBotTestFixture.cs | 12 +- .../Admin Bot/ChannelAdminBotTests.cs | 58 +- .../ChatMemberAdministrationTestFixture.cs | 13 +- .../ChatMemberAdministrationTests.cs | 216 ++++--- .../Admin Bot/SupergroupAdminBotTests.cs | 197 ++++--- .../SupergroupAdminBotTestsFixture.cs | 29 +- .../Exceptions/ApiExceptionsTests.cs | 24 +- .../Exceptions/ApiExceptionsTests2.cs | 59 +- .../Fixtures/AsyncLifetimeFixture.cs | 67 +-- .../Framework/Fixtures/ChannelChatFixture.cs | 10 +- .../Framework/Fixtures/PrivateChatFixture.cs | 9 +- .../Framework/OrderedFactAttribute.cs | 4 +- .../Framework/TestCollectionOrderer.cs | 4 +- .../Framework/TestsFixture.cs | 119 ++-- .../Framework/UpdateReceiver.cs | 2 +- .../AssemblyFixtureAttribute.cs | 9 +- .../XunitExtensions/DelayedMessageBus.cs | 7 +- .../XunitExtensions/RetryFactDiscoverer.cs | 11 +- ...itTestAssemblyRunnerWithAssemblyFixture.cs | 32 +- ...TestCollectionRunnerWithAssemblyFixture.cs | 44 +- ...estFrameworkExecutorWithAssemblyFixture.cs | 13 +- .../XunitTestFrameworkWithAssemblyFixture.cs | 6 +- .../Games/GamesExceptionTests.cs | 34 +- .../Games/GamesFixture.cs | 15 +- .../Games/GamesTests.cs | 83 +-- .../Games/GamesTests2.cs | 102 ++-- .../Getting Updates/GettingUpdatesTests.cs | 11 +- .../Getting Updates/WebhookTests.cs | 33 +- .../Inline Keyboard/CallbackQueryTests.cs | 66 ++- .../Inline Mode/InlineQueryTests.cs | 373 ++++++------ .../InlineMessageLiveLocationTests .cs | 72 +-- .../Location/LiveLocationTests.cs | 61 +- .../Other/BotCommandsTests.cs | 72 ++- .../Other/BotDescriptionTests.cs | 19 +- .../Other/BotShortDescriptionTests.cs | 40 +- .../Other/ChatInfoTests.cs | 25 +- .../Other/DiceTests.cs | 49 +- .../Other/FileDownloadTests.cs | 36 +- .../Other/GetUserProfileTests.cs | 13 +- .../Other/LeaveChatTests.cs | 13 +- .../Payments/PaymentFixture.cs | 13 +- .../Payments/PaymentTests.cs | 167 +++--- .../Payments/PaymentsBuilder.cs | 78 +-- .../Polls/AnonymousPollTests.cs | 43 +- .../Polls/AnonymousPollTestsFixture.cs | 9 +- .../Polls/PublicPollTests.cs | 44 +- .../Polls/PublicPollTestsFixture.cs | 9 +- .../Polls/QuizPollTests.cs | 48 +- .../Polls/QuizPollTestsFixture.cs | 9 +- .../Polls/SelfStoppingPollTests.cs | 42 +- .../Polls/SelfStoppingPollTestsFixture.cs | 9 +- .../PrivateChatReplyMarkupTests.cs | 105 ++-- .../ReplyMarkup/ReplyMarkupTests.cs | 48 +- .../Sending Messages/AlbumMessageTests.cs | 199 ++++--- .../Sending Messages/AnimationMessageTests.cs | 40 +- .../Sending Messages/AudioMessageTests.cs | 47 +- .../Sending Messages/CopyMessageTests.cs | 46 +- .../Sending Messages/DocumentMessageTests.cs | 38 +- .../SendingContactMessageTests.cs | 67 +-- .../SendingPhotoMessageTests.cs | 80 +-- .../SendingVenueMessageTests.cs | 45 +- .../Sending Messages/TextMessageTests.cs | 173 +++--- .../Sending Messages/VideoMessageTests.cs | 55 +- .../Stickers/StickersTests.cs | 547 ++++++++++-------- .../Stickers/StickersTestsFixture.cs | 76 ++- .../Update Messages/DeleteMessageTests.cs | 52 +- .../Update Messages/DeleteMessageTests2.cs | 45 +- .../EditMessageContentTests.cs | 102 ++-- .../EditMessageContentTests2.cs | 80 +-- .../Update Messages/EditMessageMediaTests.cs | 83 +-- .../Update Messages/EditMessageMediaTests2.cs | 73 ++- 71 files changed, 2457 insertions(+), 2077 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTestFixture.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTestFixture.cs index eb83ea138..2a351742f 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTestFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTestFixture.cs @@ -1,4 +1,5 @@ using System.IO; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; @@ -17,7 +18,7 @@ public class ChannelAdminBotTestFixture : AsyncLifetimeFixture public ChannelAdminBotTestFixture(TestsFixture fixture) { AddLifetime( - initialize: async () => + initializer: async () => { _channelChatFixture = new(fixture, Constants.TestCollections.ChannelAdminBots); await _channelChatFixture.InitializeAsync(); @@ -30,15 +31,18 @@ public ChannelAdminBotTestFixture(TestsFixture fixture) _oldChatPhoto = stream.ToArray(); } }, - dispose: async () => + finalizer: async () => { // If chat had a photo before, reset the photo back. if (_oldChatPhoto is not null) { await using MemoryStream photoStream = new(_oldChatPhoto); await fixture.BotClient.SetChatPhotoAsync( - chatId: Chat.Id, - photo: new InputFileStream(photoStream) + new() + { + ChatId = Chat.Id, + Photo = InputFile.FromStream(photoStream), + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs index ad0f757ab..cb1d5cc53 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChannelAdminBotTests.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -26,8 +27,11 @@ public class ChannelAdminBotTests(TestsFixture testsFixture, ChannelAdminBotTest public async Task Should_Set_Chat_Title() { await BotClient.SetChatTitleAsync( - chatId: _classFixture.Chat.Id, - title: "Test Chat Title" + new() + { + ChatId = _classFixture.Chat.Id, + Title = "Test Chat Title", + } ); } @@ -40,8 +44,11 @@ await BotClient.SetChatTitleAsync( public async Task Should_Set_Chat_Description() { await BotClient.SetChatDescriptionAsync( - chatId: _classFixture.Chat.Id, - description: "Test Chat Description" + new SetChatDescriptionRequest + { + ChatId = _classFixture.Chat.Id, + Description = "Test Chat Description", + } ); } @@ -49,7 +56,7 @@ await BotClient.SetChatDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetChatDescription)] public async Task Should_Delete_Chat_Description() { - await BotClient.SetChatDescriptionAsync(_classFixture.Chat.Id); + await BotClient.SetChatDescriptionAsync(new SetChatDescriptionRequest { ChatId = _classFixture.Chat.Id }); } #endregion @@ -60,12 +67,19 @@ public async Task Should_Delete_Chat_Description() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.PinChatMessage)] public async Task Should_Pin_Message() { - Message msg = await BotClient.SendTextMessageAsync(_classFixture.Chat.Id, "Description to pin"); + Message msg = await BotClient.SendMessageAsync(new() + { + ChatId = _classFixture.Chat.Id, + Text = "Description to pin", + }); await BotClient.PinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: msg.MessageId, - disableNotification: true + new() + { + ChatId = _classFixture.Chat.Id, + MessageId = msg.MessageId, + DisableNotification = true, + } ); _classFixture.PinnedMessage = msg; @@ -77,8 +91,9 @@ public async Task Should_Get_Chat_Pinned_Message() { Message pinnedMsg = _classFixture.PinnedMessage; - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = _classFixture.Chat.Id}); + Assert.NotNull(chat.PinnedMessage); Assert.True(JToken.DeepEquals( JToken.FromObject(pinnedMsg), JToken.FromObject(chat.PinnedMessage) )); @@ -88,14 +103,14 @@ public async Task Should_Get_Chat_Pinned_Message() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UnpinChatMessage)] public async Task Should_Unpin_Message() { - await BotClient.UnpinChatMessageAsync(_classFixture.Chat.Id); + await BotClient.UnpinChatMessageAsync(new UnpinChatMessageRequest { ChatId = _classFixture.Chat.Id}); } [OrderedFact("Should get the chat info without a pinned message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetChat)] public async Task Should_Get_Chat_With_No_Pinned_Message() { - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = _classFixture.Chat.Id}); Assert.Null(chat.PinnedMessage); } @@ -110,8 +125,11 @@ public async Task Should_Set_Chat_Photo() { await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); await BotClient.SetChatPhotoAsync( - chatId: _classFixture.Chat.Id, - photo: new InputFileStream(stream) + new() + { + ChatId = _classFixture.Chat.Id, + Photo = InputFile.FromStream(stream), + } ); } @@ -119,7 +137,7 @@ await BotClient.SetChatPhotoAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetChat)] public async Task Should_Get_Chat_Photo() { - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = _classFixture.Chat.Id }); Assert.NotNull(chat.Photo); Assert.NotEmpty(chat.Photo.BigFileId); @@ -132,7 +150,7 @@ public async Task Should_Get_Chat_Photo() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteChatPhoto)] public async Task Should_Delete_Chat_Photo() { - await BotClient.DeleteChatPhotoAsync(_classFixture.Chat.Id); + await BotClient.DeleteChatPhotoAsync(new DeleteChatPhotoRequest { ChatId = _classFixture.Chat.Id }); } [OrderedFact("Should throw exception in deleting chat photo with no photo currently set")] @@ -140,7 +158,7 @@ public async Task Should_Delete_Chat_Photo() public async Task Should_Throw_On_Deleting_Chat_Deleted_Photo() { ApiRequestException e = await Assert.ThrowsAsync( - async () => await BotClient.DeleteChatPhotoAsync(_classFixture.Chat.Id) + async () => await BotClient.DeleteChatPhotoAsync(new DeleteChatPhotoRequest() { ChatId = _classFixture.Chat.Id }) ); Assert.IsType(e); @@ -158,7 +176,11 @@ public async Task Should_Throw_On_Setting_Chat_Sticker_Set() const string setName = "EvilMinds"; ApiRequestException exception = await Assert.ThrowsAsync(async () => - await _fixture.BotClient.SetChatStickerSetAsync(_classFixture.Chat.Id, setName) + await _fixture.BotClient.SetChatStickerSetAsync(new() + { + ChatId = _classFixture.Chat.Id, + StickerSetName = setName, + }) ); Assert.Equal(400, exception.ErrorCode); diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs index 59b58dc75..81380fc14 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTestFixture.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -9,8 +10,6 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; public class ChatMemberAdministrationTestFixture(TestsFixture testsFixture) : IAsyncLifetime { - readonly TestsFixture _testsFixture = testsFixture; - public Chat RegularMemberChat { get; private set; } public long RegularMemberUserId { get; private set; } public string RegularMemberUserName { get; private set; } @@ -24,7 +23,7 @@ static async Task GetChat(TestsFixture testsFixture, string collectionName if (testsFixture.Configuration.RegularGroupMemberId is {} userId) { - chat = await testsFixture.BotClient.GetChatAsync(userId); + chat = await testsFixture.BotClient.GetChatAsync(new GetChatRequest {ChatId = userId}); } else { @@ -52,9 +51,9 @@ public async Task InitializeAsync() { const string collectionName = Constants.TestCollections.ChatMemberAdministration; - RegularMemberChat = await GetChat(_testsFixture, collectionName); + RegularMemberChat = await GetChat(testsFixture, collectionName); - await _testsFixture.SendTestCollectionNotificationAsync( + await testsFixture.SendTestCollectionNotificationAsync( collectionName, $"Chosen regular member is @{RegularMemberChat.GetSafeUsername()}" ); @@ -62,13 +61,13 @@ await _testsFixture.SendTestCollectionNotificationAsync( RegularMemberUserId = RegularMemberChat.Id; RegularMemberUserName = RegularMemberChat.Username; // Updates from regular user will be received - _testsFixture.UpdateReceiver.AllowedUsernames.Add(RegularMemberUserName); + testsFixture.UpdateReceiver.AllowedUsernames.Add(RegularMemberUserName); } public Task DisposeAsync() { // Remove regular user from AllowedUserNames - _testsFixture.UpdateReceiver.AllowedUsernames.Remove(RegularMemberUserName); + testsFixture.UpdateReceiver.AllowedUsernames.Remove(RegularMemberUserName); return Task.CompletedTask; } } diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs index ebfe51b63..c18def498 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/ChatMemberAdministrationTests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -28,8 +29,11 @@ public class ChatMemberAdministrationTests(TestsFixture fixture, ChatMemberAdmin public async Task Should_Get_Chat_Member_Member() { ChatMember chatMember = await BotClient.GetChatMemberAsync( - chatId: _fixture.SupergroupChat, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat, + UserId = _classFixture.RegularMemberUserId, + } ); Assert.Equal(ChatMemberStatus.Member, chatMember.Status); @@ -41,8 +45,11 @@ public async Task Should_Get_Chat_Member_Member() public async Task Should_Kick_Chat_Member_For_Ever() { await BotClient.BanChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } ); } @@ -50,8 +57,11 @@ await BotClient.BanChatMemberAsync( public async Task Should_Get_Chat_Member_Kicked() { ChatMember chatMember = await BotClient.GetChatMemberAsync( - chatId: _fixture.SupergroupChat, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat, + UserId = _classFixture.RegularMemberUserId, + } ); Assert.Equal(ChatMemberStatus.Kicked, chatMember.Status); @@ -65,8 +75,11 @@ public async Task Should_Get_Chat_Member_Kicked() public async Task Should_Unban_Chat_Member() { await BotClient.UnbanChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } ); } @@ -74,7 +87,9 @@ await BotClient.UnbanChatMemberAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.ExportChatInviteLink)] public async Task Should_Export_Chat_Invite_Link() { - string chatInviteLink = await BotClient.ExportChatInviteLinkAsync(_fixture.SupergroupChat.Id); + string chatInviteLink = await BotClient.ExportChatInviteLinkAsync( + new ExportChatInviteLinkRequest { ChatId = _fixture.SupergroupChat.Id} + ); Assert.Matches("https://t.me/.+", chatInviteLink); @@ -91,9 +106,12 @@ await _fixture.SendTestInstructionsAsync( await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); - Message privateMessage = await BotClient.SendTextMessageAsync( - chatId: _classFixture.RegularMemberChat, - text: _classFixture.GroupInviteLink + Message privateMessage = await BotClient.SendMessageAsync( + new() + { + ChatId = _classFixture.RegularMemberChat, + Text = _classFixture.GroupInviteLink, + } ); Update update = await _fixture.UpdateReceiver.GetUpdateAsync( @@ -105,8 +123,12 @@ await _fixture.SendTestInstructionsAsync( ); await BotClient.DeleteMessageAsync( - chatId: _classFixture.RegularMemberChat, - messageId: privateMessage.MessageId); + new() + { + ChatId = _classFixture.RegularMemberChat, + MessageId = privateMessage.MessageId, + } + ); await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); @@ -136,10 +158,13 @@ public async Task Should_Create_Chat_Invite_Link() string inviteLinkName = $"Created at {createdAt:yyyy-MM-ddTHH:mm:ss}"; ChatInviteLink chatInviteLink = await BotClient.CreateChatInviteLinkAsync( - chatId: _fixture.SupergroupChat.Id, - createsJoinRequest: true, - name: inviteLinkName, - expireDate: expireDate + new CreateChatInviteLinkRequest + { + ChatId = _fixture.SupergroupChat.Id, + CreatesJoinRequest = true, + Name = inviteLinkName, + ExpireDate = expireDate, + } ); Assert.NotNull(chatInviteLink); @@ -167,20 +192,31 @@ await _fixture.SendTestInstructionsAsync( ); await BotClient.BanChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId); + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } + ); await Task.Delay(TimeSpan.FromSeconds(5)); await BotClient.UnbanChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId); + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } + ); await Task.Delay(TimeSpan.FromSeconds(5)); - Message privateMessage = await BotClient.SendTextMessageAsync( - chatId: _classFixture.RegularMemberChat, - text: _classFixture.ChatInviteLink.InviteLink + Message privateMessage = await BotClient.SendMessageAsync( + new() + { + ChatId = _classFixture.RegularMemberChat, + Text = _classFixture.ChatInviteLink.InviteLink, + } ); await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); @@ -191,8 +227,12 @@ await BotClient.UnbanChatMemberAsync( ); await BotClient.DeleteMessageAsync( - chatId: _classFixture.RegularMemberChat, - messageId: privateMessage.MessageId); + new() + { + ChatId = _classFixture.RegularMemberChat, + MessageId = privateMessage.MessageId, + } + ); ChatJoinRequest chatJoinRequest = update.ChatJoinRequest; @@ -212,9 +252,12 @@ await BotClient.DeleteMessageAsync( public async Task Should_Decline_Chat_Join_Request() { Exception exception = await Record.ExceptionAsync(async () => - await BotClient.DeclineChatJoinRequest( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId + await BotClient.DeclineChatJoinRequestAsync( + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } ) ); Assert.Null(exception); @@ -224,9 +267,12 @@ await BotClient.DeclineChatJoinRequest( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.ApproveChatJoinRequest)] public async Task Should_Approve_Chat_Join_Request() { - Message privateMessage = await BotClient.SendTextMessageAsync( - chatId: _classFixture.RegularMemberChat, - text: _classFixture.ChatInviteLink.InviteLink + Message privateMessage = await BotClient.SendMessageAsync( + new() + { + ChatId = _classFixture.RegularMemberChat, + Text = _classFixture.ChatInviteLink.InviteLink, + } ); await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); @@ -237,8 +283,12 @@ public async Task Should_Approve_Chat_Join_Request() ); await BotClient.DeleteMessageAsync( - chatId: _classFixture.RegularMemberChat, - messageId: privateMessage.MessageId); + new() + { + ChatId = _classFixture.RegularMemberChat, + MessageId = privateMessage.MessageId, + } + ); ChatJoinRequest chatJoinRequest = update.ChatJoinRequest; @@ -251,9 +301,12 @@ await BotClient.DeleteMessageAsync( Assert.Equal(chatJoinRequest.From.Id, _classFixture.RegularMemberUserId); Exception exception = await Record.ExceptionAsync(async () => - await BotClient.ApproveChatJoinRequest( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId + await BotClient.ApproveChatJoinRequestAsync( + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + } ) ); Assert.Null(exception); @@ -270,9 +323,12 @@ public async Task Should_Promote_User_To_Change_Chat_Info() //ToDo exception when user isn't in group. Bad Request: bots can't add new chat members await BotClient.PromoteChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId, - canChangeInfo: true + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + CanChangeInfo = true, + } ); } @@ -281,19 +337,28 @@ await BotClient.PromoteChatMemberAsync( public async Task Should_Set_Custom_Title_For_Admin() { ChatMember promotedRegularUser = await BotClient.GetChatMemberAsync( - _fixture.SupergroupChat, - _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat, + UserId = _classFixture.RegularMemberUserId, + } ); await BotClient.SetChatAdministratorCustomTitleAsync( - chatId: _fixture.SupergroupChat, - userId: promotedRegularUser.User.Id, - customTitle: "CHANGED TITLE" + new() + { + ChatId = _fixture.SupergroupChat, + UserId = promotedRegularUser.User.Id, + CustomTitle = "CHANGED TITLE", + } ); ChatMember newChatMember = await BotClient.GetChatMemberAsync( - _fixture.SupergroupChat, - promotedRegularUser.User.Id + new() + { + ChatId = _fixture.SupergroupChat, + UserId = promotedRegularUser.User.Id, + } ); Assert.Equal(ChatMemberStatus.Administrator, newChatMember.Status); @@ -303,9 +368,12 @@ await BotClient.SetChatAdministratorCustomTitleAsync( // Restore default title by sending empty string await BotClient.SetChatAdministratorCustomTitleAsync( - chatId: _fixture.SupergroupChat, - userId: promotedRegularUser.User.Id, - customTitle: "" + new() + { + ChatId = _fixture.SupergroupChat, + UserId = promotedRegularUser.User.Id, + CustomTitle = "", + } ); } @@ -316,9 +384,12 @@ public async Task Should_Demote_User() //ToDo exception when user isn't in group. Bad Request: USER_NOT_MUTUAL_CONTACT await BotClient.PromoteChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId, - canChangeInfo: false + new() + { + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + CanChangeInfo = false, + } ); } @@ -329,13 +400,16 @@ public async Task Should_Restrict_Sending_Stickers_Temporarily() const int banSeconds = 35; await BotClient.RestrictChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId, - untilDate: DateTime.UtcNow.AddSeconds(banSeconds), - permissions: new ChatPermissions + new() { - CanSendMessages = true, - CanSendOtherMessages = false + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + UntilDate = DateTime.UtcNow.AddSeconds(banSeconds), + Permissions = new() + { + CanSendMessages = true, + CanSendOtherMessages = false + }, } ); } @@ -344,8 +418,11 @@ await BotClient.RestrictChatMemberAsync( public async Task Should_Get_Chat_Member_Restricted() { ChatMember chatMember = await BotClient.GetChatMemberAsync( - chatId: _fixture.SupergroupChat, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat, + UserId = _classFixture.RegularMemberUserId, + } ); Assert.Equal(ChatMemberStatus.Restricted, chatMember.Status); @@ -432,9 +509,11 @@ await _fixture.SendTestInstructionsAsync( ); await BotClient.BanChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _classFixture.RegularMemberUserId, - untilDate: DateTime.UtcNow.AddSeconds(banSeconds) + new(){ + ChatId = _fixture.SupergroupChat.Id, + UserId = _classFixture.RegularMemberUserId, + UntilDate = DateTime.UtcNow.AddSeconds(banSeconds), + } ); } @@ -442,8 +521,11 @@ await BotClient.BanChatMemberAsync( public async Task Should_Get_Chat_Member_Restricted_With_Until_Date() { ChatMember chatMember = await BotClient.GetChatMemberAsync( - chatId: _fixture.SupergroupChat, - userId: _classFixture.RegularMemberUserId + new() + { + ChatId = _fixture.SupergroupChat, + UserId = _classFixture.RegularMemberUserId, + } ); Assert.Equal(ChatMemberStatus.Kicked, chatMember.Status); diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs index befb39cb7..0284bba9a 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -15,9 +16,7 @@ namespace Telegram.Bot.Tests.Integ.Admin_Bot; public class SupergroupAdminBotTests(SupergroupAdminBotTestsFixture classFixture) : IClassFixture { - readonly SupergroupAdminBotTestsFixture _classFixture = classFixture; - - ITelegramBotClient BotClient => _classFixture.TestsFixture.BotClient; + ITelegramBotClient BotClient => classFixture.TestsFixture.BotClient; #region 1. Changing Chat Title @@ -26,8 +25,11 @@ public class SupergroupAdminBotTests(SupergroupAdminBotTestsFixture classFixture public async Task Should_Set_Chat_Title() { await BotClient.SetChatTitleAsync( - chatId: _classFixture.Chat.Id, - title: "Test Chat Title" + new() + { + ChatId = classFixture.Chat.Id, + Title = "Test Chat Title", + } ); } @@ -42,27 +44,30 @@ public async Task Should_Set_New_Default_Permissions() ChatPermissions newDefaultPermissions = new() { CanSendMessages = true, - CanSendAudios=false, - CanSendDocuments=true, - CanSendPhotos=false, - CanSendVideos=false, - CanSendVideoNotes=false, - CanSendVoiceNotes=true, - CanSendPolls=false, - CanSendOtherMessages=false, - CanAddWebPagePreviews=false, - CanChangeInfo=false, - CanInviteUsers=false, - CanPinMessages=false, - CanManageTopics=false, + CanSendAudios = false, + CanSendDocuments = true, + CanSendPhotos =false, + CanSendVideos = false, + CanSendVideoNotes = false, + CanSendVoiceNotes = true, + CanSendPolls = false, + CanSendOtherMessages = false, + CanAddWebPagePreviews = false, + CanChangeInfo = false, + CanInviteUsers = false, + CanPinMessages = false, + CanManageTopics = false, }; - await BotClient.SetChatPermissionsAsync(_classFixture.Chat.Id, newDefaultPermissions); - - Chat supergroup = await BotClient.GetChatAsync(_classFixture.Chat.Id); - ChatPermissions setChatPermissions = supergroup.Permissions!; + await BotClient.SetChatPermissionsAsync(new() + { + ChatId = classFixture.Chat.Id, + Permissions = newDefaultPermissions, + }); - Asserts.JsonEquals(newDefaultPermissions, setChatPermissions); + Chat supergroup = await BotClient.GetChatAsync(new GetChatRequest { ChatId = classFixture.Chat.Id }); + Assert.NotNull(supergroup.Permissions); + Asserts.JsonEquals(newDefaultPermissions, supergroup.Permissions); } #endregion @@ -74,8 +79,11 @@ public async Task Should_Set_New_Default_Permissions() public async Task Should_Set_Chat_Description() { await BotClient.SetChatDescriptionAsync( - chatId: _classFixture.Chat.Id, - description: "Test Chat Description" + new SetChatDescriptionRequest + { + ChatId = classFixture.Chat.Id, + Description = "Test Chat Description", + } ); } @@ -86,7 +94,7 @@ public async Task Should_Delete_Chat_Description() // ToDo: exception Bad Request: chat description is not modified await BotClient.SetChatDescriptionAsync( - chatId: _classFixture.Chat.Id + new SetChatDescriptionRequest { ChatId = classFixture.Chat.Id, } ); } @@ -98,47 +106,60 @@ await BotClient.SetChatDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.PinChatMessage)] public async Task Should_Pin_Message() { - Message msg1 = await _classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This message will be deleted second"); - Message msg2 = await _classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This will be deleted as group"); - Message msg3 = await _classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This will be deleted with previous one"); - Message msg4 = await _classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This message will be deleted first"); + Message msg1 = await classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This message will be deleted second"); + Message msg2 = await classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This will be deleted as group"); + Message msg3 = await classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This will be deleted with previous one"); + Message msg4 = await classFixture.TestsFixture.SendTestInstructionsAsync("🧷 This message will be deleted first"); await BotClient.PinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: msg1.MessageId, - disableNotification: true + new() + { + ChatId = classFixture.Chat.Id, + MessageId = msg1.MessageId, + DisableNotification = true, + } ); await BotClient.PinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: msg2.MessageId, - disableNotification: true + new() + { + ChatId = classFixture.Chat.Id, + MessageId = msg2.MessageId, + DisableNotification = true, + } ); await BotClient.PinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: msg3.MessageId, - disableNotification: true + new() + { + ChatId = classFixture.Chat.Id, + MessageId = msg3.MessageId, + DisableNotification = true, + } ); await BotClient.PinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: msg4.MessageId, - disableNotification: true + new() + { + ChatId = classFixture.Chat.Id, + MessageId = msg4.MessageId, + DisableNotification = true, + } ); - _classFixture.PinnedMessages.Add(msg1); - _classFixture.PinnedMessages.Add(msg2); - _classFixture.PinnedMessages.Add(msg3); - _classFixture.PinnedMessages.Add(msg4); + + classFixture.PinnedMessages.Add(msg1); + classFixture.PinnedMessages.Add(msg2); + classFixture.PinnedMessages.Add(msg3); + classFixture.PinnedMessages.Add(msg4); } [OrderedFact("Should get chat’s pinned message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetChat)] public async Task Should_Get_Last_Chat_Pinned_Message() { - Message pinnedMsg = _classFixture.PinnedMessages.Last(); + Message pinnedMsg = classFixture.PinnedMessages.Last(); - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = classFixture.Chat.Id }); Assert.NotNull(chat.PinnedMessage); Assert.True(JToken.DeepEquals( @@ -150,14 +171,14 @@ public async Task Should_Get_Last_Chat_Pinned_Message() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UnpinChatMessage)] public async Task Should_Unpin_Last_Message() { - await BotClient.UnpinChatMessageAsync(_classFixture.Chat.Id); + await BotClient.UnpinChatMessageAsync(new UnpinChatMessageRequest { ChatId = classFixture.Chat.Id }); // Wait for chat object to update on Telegram servers await Task.Delay(TimeSpan.FromSeconds(5)); - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = classFixture.Chat.Id }); - Message secondsFromEndPinnedMessage = _classFixture.PinnedMessages[^2]; + Message secondsFromEndPinnedMessage = classFixture.PinnedMessages[^2]; Assert.NotNull(chat.PinnedMessage); Assert.True(JToken.DeepEquals( @@ -171,8 +192,11 @@ public async Task Should_Unpin_Last_Message() public async Task Should_Unpin_First_Message() { await BotClient.UnpinChatMessageAsync( - chatId: _classFixture.Chat.Id, - messageId: _classFixture.PinnedMessages.First().MessageId + new UnpinChatMessageRequest + { + ChatId = classFixture.Chat.Id, + MessageId = classFixture.PinnedMessages.First().MessageId, + } ); } @@ -180,14 +204,14 @@ await BotClient.UnpinChatMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.UnpinAllChatMessages)] public async Task Should_Unpin_All_Messages() { - await BotClient.UnpinAllChatMessages(_classFixture.Chat); + await BotClient.UnpinAllChatMessagesAsync(new() { ChatId = classFixture.Chat }); } [OrderedFact("Should get the chat info without a pinned message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetChat)] public async Task Should_Get_Chat_With_No_Pinned_Message() { - Chat chat = await BotClient.GetChatAsync(_classFixture.Chat.Id); + Chat chat = await BotClient.GetChatAsync(new GetChatRequest { ChatId = classFixture.Chat.Id }); Assert.Null(chat.PinnedMessage); } @@ -202,8 +226,11 @@ public async Task Should_Set_Chat_Photo() { await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); await BotClient.SetChatPhotoAsync( - chatId: _classFixture.Chat.Id, - photo: new InputFileStream(stream) + new() + { + ChatId = classFixture.Chat.Id, + Photo = InputFile.FromStream(stream), + } ); } @@ -211,7 +238,7 @@ await BotClient.SetChatPhotoAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteChatPhoto)] public async Task Should_Delete_Chat_Photo() { - await BotClient.DeleteChatPhotoAsync(_classFixture.Chat.Id); + await BotClient.DeleteChatPhotoAsync(new DeleteChatPhotoRequest { ChatId = classFixture.Chat.Id }); } [OrderedFact("Should throw exception in deleting chat photo with no photo currently set")] @@ -219,7 +246,7 @@ public async Task Should_Delete_Chat_Photo() public async Task Should_Throw_On_Deleting_Chat_Deleted_Photo() { ApiRequestException e = await Assert.ThrowsAsync( - () => BotClient.DeleteChatPhotoAsync(_classFixture.Chat.Id) + () => BotClient.DeleteChatPhotoAsync(new DeleteChatPhotoRequest { ChatId = classFixture.Chat.Id }) ); Assert.IsType(e); @@ -237,7 +264,11 @@ public async Task Should_Throw_On_Setting_Chat_Sticker_Set() const string setName = "EvilMinds"; ApiRequestException exception = await Assert.ThrowsAsync(() => - BotClient.SetChatStickerSetAsync(_classFixture.Chat.Id, setName) + BotClient.SetChatStickerSetAsync(new() + { + ChatId = classFixture.Chat.Id, + StickerSetName = setName, + }) ); Assert.Equal(400, exception.ErrorCode); @@ -261,15 +292,19 @@ public async Task Should_Create_Chat_Invite_Link() string inviteLinkName = $"Created at {createdAt:yyyy-MM-ddTHH:mm:ss}Z"; ChatInviteLink chatInviteLink = await BotClient.CreateChatInviteLinkAsync( - chatId: _classFixture.TestsFixture.SupergroupChat.Id, - name: inviteLinkName, - expireDate: expireDate, - createsJoinRequest: true); + new CreateChatInviteLinkRequest + { + ChatId = classFixture.TestsFixture.SupergroupChat.Id, + Name = inviteLinkName, + ExpireDate = expireDate, + CreatesJoinRequest = true, + } + ); Assert.NotNull(chatInviteLink); Assert.NotNull(chatInviteLink.Creator); - Assert.Equal(_classFixture.TestsFixture.BotUser.Id, chatInviteLink.Creator.Id); - Assert.Equal(_classFixture.TestsFixture.BotUser.Username, chatInviteLink.Creator.Username); + Assert.Equal(classFixture.TestsFixture.BotUser.Id, chatInviteLink.Creator.Id); + Assert.Equal(classFixture.TestsFixture.BotUser.Username, chatInviteLink.Creator.Username); Assert.True(chatInviteLink.Creator.IsBot); Assert.NotNull(chatInviteLink.InviteLink); Assert.Matches("https://t.me/.+", chatInviteLink.InviteLink); @@ -281,7 +316,7 @@ public async Task Should_Create_Chat_Invite_Link() Assert.Equal(inviteLinkName, chatInviteLink.Name); Assert.Equal(expireDate, chatInviteLink.ExpireDate); - _classFixture.ChatInviteLink = chatInviteLink; + classFixture.ChatInviteLink = chatInviteLink; } [OrderedFact("Should edit previously created invite link to the group")] @@ -297,15 +332,18 @@ public async Task Should_Edit_Chat_Invite_Link() string inviteLinkName = $"Edited at {editedAt:yyyy-MM-ddTHH:mm:ss}Z"; ChatInviteLink editedChatInviteLink = await BotClient.EditChatInviteLinkAsync( - chatId: _classFixture.TestsFixture.SupergroupChat.Id, - inviteLink: _classFixture.ChatInviteLink.InviteLink, - name: inviteLinkName, - expireDate: expireDate, - memberLimit: 100, - createsJoinRequest: false + new() + { + ChatId = classFixture.TestsFixture.SupergroupChat.Id, + InviteLink = classFixture.ChatInviteLink.InviteLink, + Name = inviteLinkName, + ExpireDate = expireDate, + MemberLimit = 100, + CreatesJoinRequest = false, + } ); - ChatInviteLink chatInviteLink = _classFixture.ChatInviteLink; + ChatInviteLink chatInviteLink = classFixture.ChatInviteLink; Assert.NotNull(editedChatInviteLink); Assert.NotNull(editedChatInviteLink.Creator); @@ -319,7 +357,7 @@ public async Task Should_Edit_Chat_Invite_Link() Assert.Equal(chatInviteLink.PendingJoinRequestCount, editedChatInviteLink.PendingJoinRequestCount); Assert.Equal(chatInviteLink.IsRevoked, editedChatInviteLink.IsRevoked); - _classFixture.ChatInviteLink = editedChatInviteLink; + classFixture.ChatInviteLink = editedChatInviteLink; } #endregion @@ -329,11 +367,14 @@ public async Task Should_Edit_Chat_Invite_Link() public async Task Should_Revoke_Chat_Invite_Link() { ChatInviteLink revokedChatInviteLink = await BotClient.RevokeChatInviteLinkAsync( - chatId: _classFixture.TestsFixture.SupergroupChat.Id, - inviteLink: _classFixture.ChatInviteLink.InviteLink + new() + { + ChatId = classFixture.TestsFixture.SupergroupChat.Id, + InviteLink = classFixture.ChatInviteLink.InviteLink, + } ); - ChatInviteLink editedChatInviteLink = _classFixture.ChatInviteLink; + ChatInviteLink editedChatInviteLink = classFixture.ChatInviteLink; Assert.NotNull(revokedChatInviteLink); Assert.NotNull(revokedChatInviteLink.Creator); diff --git a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTestsFixture.cs index 718988bfd..5c12c81cf 100644 --- a/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Admin Bot/SupergroupAdminBotTestsFixture.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; @@ -22,9 +23,9 @@ public SupergroupAdminBotTestsFixture(TestsFixture testsFixture) PinnedMessages = new(3); AddLifetime( - initialize: async () => + initializer: async () => { - Chat chat = await TestsFixture.BotClient.GetChatAsync(TestsFixture.SupergroupChat); + Chat chat = await TestsFixture.BotClient.GetChatAsync(new GetChatRequest { ChatId = TestsFixture.SupergroupChat }); // Save existing chat photo as byte[] to restore it later because Bot API 4.4+ invalidates old // file_ids after changing chat photo @@ -39,31 +40,39 @@ public SupergroupAdminBotTestsFixture(TestsFixture testsFixture) // Save default permissions so they can be restored _existingDefaultPermissions = chat.Permissions!; }, - dispose: async () => + finalizer: async () => { // If chat had a photo before, reset the photo back. if (_oldChatPhoto is not null) { await using MemoryStream photoStream = new(_oldChatPhoto); await TestsFixture.BotClient.SetChatPhotoAsync( - chatId: Chat.Id, - photo: new InputFileStream(photoStream) + new() + { + ChatId = Chat.Id, + Photo = InputFile.FromStream(photoStream), + } ); } // Reset original default permissions await TestsFixture.BotClient.SetChatPermissionsAsync( - TestsFixture.SupergroupChat, - _existingDefaultPermissions! - + new() + { + ChatId = TestsFixture.SupergroupChat, + Permissions = _existingDefaultPermissions!, + } ); // Revoke invite link created during the test run if (ChatInviteLink is not null) { await TestsFixture.BotClient.RevokeChatInviteLinkAsync( - chatId: TestsFixture.SupergroupChat, - inviteLink: ChatInviteLink.InviteLink + new() + { + ChatId = TestsFixture.SupergroupChat, + InviteLink = ChatInviteLink.InviteLink, + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs index 0ebf8cebe..5d4510dd4 100644 --- a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests.cs @@ -1,8 +1,6 @@ using System.Threading.Tasks; using Telegram.Bot.Exceptions; using Telegram.Bot.Tests.Integ.Framework; -using Telegram.Bot.Types; -using Telegram.Bot.Types.Enums; using Xunit; namespace Telegram.Bot.Tests.Integ.Exceptions; @@ -10,16 +8,9 @@ namespace Telegram.Bot.Tests.Integ.Exceptions; [Collection(Constants.TestCollections.Exceptions)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ApiExceptionsTests +public class ApiExceptionsTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public ApiExceptionsTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should throw ChatNotFoundException while trying to send message to a user who hasn't " + "started a chat with bot but bot knows about him/her.")] @@ -27,7 +18,7 @@ public ApiExceptionsTests(TestsFixture fixture) public async Task Should_Throw_Exception_ChatNotFoundException() { //ToDo add exception. forward message from another bot. Forbidden: bot can't send messages to bots - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Forward a message to this chat from a user that never started a chat with this bot" ); @@ -41,9 +32,12 @@ await _fixture.SendTestInstructionsAsync( //MessageOriginHiddenUser hiddenUser = (MessageOriginHiddenUser)forwardedMessageUpdate.Message!.ForwardOrigin; ApiRequestException e = await Assert.ThrowsAsync(async () => - await BotClient.SendTextMessageAsync( - int.MaxValue, - $"Error!" + await BotClient.SendMessageAsync( + new() + { + ChatId = int.MaxValue, + Text = "Error!", + } ) ); diff --git a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs index 542fb0ec7..d2e17729f 100644 --- a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.ReplyMarkups; @@ -9,23 +10,22 @@ namespace Telegram.Bot.Tests.Integ.Exceptions; [Collection(Constants.TestCollections.Exceptions2)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ApiExceptionsTests2 +public class ApiExceptionsTests2(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public ApiExceptionsTests2(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should throw ChatNotFoundException while trying to send message to an invalid chat")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Throw_Exception_ChatNotFoundException() { ApiRequestException e = await Assert.ThrowsAsync(() => - BotClient.SendTextMessageAsync(0, "test") + BotClient.SendMessageAsync( + new() + { + ChatId = 0, + Text = "test", + } + ) ); Assert.Equal(400, e.ErrorCode); @@ -36,7 +36,13 @@ public async Task Should_Throw_Exception_ChatNotFoundException() public async Task Should_Throw_Exception_UserNotFoundException() { ApiRequestException e = await Assert.ThrowsAsync(() => - BotClient.PromoteChatMemberAsync(_fixture.SupergroupChat.Id, 123456) + BotClient.PromoteChatMemberAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + UserId = 123456, + } + ) ); Assert.Equal(400, e.ErrorCode); @@ -53,10 +59,13 @@ public async Task Should_Throw_Exception_ApiRequestException() }); ApiRequestException exception = await Assert.ThrowsAsync(() => - BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "You should never see this message", - replyMarkup: replyMarkup + BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "You should never see this message", + ReplyMarkup = replyMarkup, + } ) ); @@ -69,19 +78,25 @@ public async Task Should_Throw_Exception_ApiRequestException() public async Task Should_Throw_Exception_MessageIsNotModifiedException() { const string messageTextToModify = "Message text to modify"; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: messageTextToModify + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = messageTextToModify, + } ); ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.EditMessageTextAsync( - chatId: _fixture.SupergroupChat.Id, - messageId: message.MessageId, - text: messageTextToModify + new EditMessageTextRequest + { + ChatId = fixture.SupergroupChat.Id, + MessageId = message.MessageId, + Text = messageTextToModify, + } ) ); Assert.Equal(400, e.ErrorCode); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/AsyncLifetimeFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/AsyncLifetimeFixture.cs index 6922a52bb..c395b0bc7 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/AsyncLifetimeFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/AsyncLifetimeFixture.cs @@ -10,16 +10,32 @@ namespace Telegram.Bot.Tests.Integ.Framework.Fixtures; public abstract class AsyncLifetimeFixture : IAsyncLifetime { - readonly List _lifetimes = new(); + readonly List _lifetimes = []; + + protected virtual IEnumerable Lifetimes() => []; + protected virtual IEnumerable> Initializers() => []; + protected virtual IEnumerable> Finalizers() => []; + + protected AsyncLifetimeFixture() + { + // ReSharper disable VirtualMemberCallInConstructor + _lifetimes.AddRange(Initializers().Select(initializer => new AsyncLifetimeAction(initializer: initializer))); + _lifetimes.AddRange(Lifetimes()); + _lifetimes.AddRange(Finalizers().Select(finalizer => new AsyncLifetimeAction(finalizer: finalizer))); + // ReSharper restore VirtualMemberCallInConstructor + } protected void AddLifetime(IAsyncLifetime lifetime) => _lifetimes.Add(lifetime); - protected void AddLifetime(Func? initialize = default, Func? dispose = default) => - _lifetimes.Add(new AsyncLifetimeAction(initialize, dispose)); + protected void AddLifetime(Func? initializer = default, Func? finalizer = default) => + _lifetimes.Add(new AsyncLifetimeAction(initializer, finalizer)); - protected void AddLifetime(Action? initialize = default, Action? dispose = default) => - _lifetimes.Add(new AsyncLifetimeAction(initialize, dispose)); + protected void AddInitializer(Func initializer) => + _lifetimes.Add(new AsyncLifetimeAction(initializer: initializer)); + + protected void AddFinalizer(Func finalizer) => + _lifetimes.Add(new AsyncLifetimeAction(finalizer: finalizer)); public async Task InitializeAsync() { @@ -31,53 +47,24 @@ public async Task InitializeAsync() public async Task DisposeAsync() { - // dispose in reverse order because later lifetimes might depend on previous lifetimes to be intact + // finalizer in reverse order because later lifetimes might depend on previous lifetimes to be intact foreach (var asyncLifetime in ((IEnumerable)_lifetimes).Reverse()) { await asyncLifetime.DisposeAsync(); } } - sealed class AsyncLifetimeAction : IAsyncLifetime + public sealed class AsyncLifetimeAction(Func? initializer = default, Func? finalizer = default) + : IAsyncLifetime { - readonly Func? _initialize; - readonly Func? _dispose; - - public AsyncLifetimeAction(Func? initialize = default, Func? dispose = default) - { - _initialize = initialize; - _dispose = dispose; - } - - public AsyncLifetimeAction(Action? initialize = default, Action? dispose = default) - { - if (initialize is not null) - { - _initialize = () => - { - initialize.Invoke(); - return Task.CompletedTask; - }; - } - - if (dispose is not null) - { - _dispose = () => - { - dispose.Invoke(); - return Task.CompletedTask; - }; - } - } - public async Task InitializeAsync() { - if (_initialize is not null) { await _initialize(); } + if (initializer is not null) { await initializer(); } } public async Task DisposeAsync() { - if (_dispose is not null) { await _dispose(); } + if (finalizer is not null) { await finalizer(); } } } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/ChannelChatFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/ChannelChatFixture.cs index 5f7b5698d..5c83c2fcf 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/ChannelChatFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/ChannelChatFixture.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -15,8 +16,8 @@ public ChannelChatFixture(TestsFixture testsFixture, string collectionName) { _testsFixture = testsFixture; - AddLifetime( - initialize: async () => + AddInitializer( + async () => { _testsFixture.ChannelChat ??= await GetChat(collectionName); ChannelChat = _testsFixture.ChannelChat; @@ -34,7 +35,8 @@ await _testsFixture.SendTestCollectionNotificationAsync( async Task GetChat(string collectionName) { var chatId = _testsFixture.Configuration.ChannelChatId; - if (chatId is not null) return await _testsFixture.BotClient.GetChatAsync(chatId.Value); + if (chatId is not null) + return await _testsFixture.BotClient.GetChatAsync(new GetChatRequest {ChatId = chatId.Value}); await _testsFixture.UpdateReceiver.DiscardNewUpdatesAsync(); @@ -46,4 +48,4 @@ await _testsFixture.SendTestCollectionNotificationAsync(collectionName, return await _testsFixture.GetChatFromTesterAsync(ChatType.Channel); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/PrivateChatFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/PrivateChatFixture.cs index ce1888912..c01cf0ff7 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/PrivateChatFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/Fixtures/PrivateChatFixture.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -10,8 +11,8 @@ public class PrivateChatFixture : AsyncLifetimeFixture public PrivateChatFixture(TestsFixture testsFixture, string collectionName) { - AddLifetime( - initialize: async () => + AddInitializer( + async () => { testsFixture.PrivateChat ??= await GetChat(testsFixture, collectionName); PrivateChat = testsFixture.PrivateChat; @@ -30,7 +31,7 @@ static async Task GetChat(TestsFixture testsFixture, string collectionName long? chatId = testsFixture.Configuration.TesterPrivateChatId; if (chatId.HasValue) { - chat = await testsFixture.BotClient.GetChatAsync(chatId); + chat = await testsFixture.BotClient.GetChatAsync(new GetChatRequest { ChatId = chatId}); } else { @@ -46,4 +47,4 @@ await testsFixture.SendTestCollectionNotificationAsync(collectionName, } return chat; } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/OrderedFactAttribute.cs b/test/Telegram.Bot.Tests.Integ/Framework/OrderedFactAttribute.cs index 61a8a00b2..3d9eb369c 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/OrderedFactAttribute.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/OrderedFactAttribute.cs @@ -78,10 +78,10 @@ public Type ExceptionType /// Line number in source file. public OrderedFactAttribute(string description, [CallerLineNumber] int line = default) { - if (line < 1) { throw new ArgumentOutOfRangeException(nameof(line)); } + ArgumentOutOfRangeException.ThrowIfLessThan(line, 1); // ReSharper disable once VirtualMemberCallInConstructor if (!string.IsNullOrWhiteSpace(description)) { DisplayName = description; } LineNumber = line; } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/TestCollectionOrderer.cs b/test/Telegram.Bot.Tests.Integ/Framework/TestCollectionOrderer.cs index 5e61a377e..ab0e508a2 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/TestCollectionOrderer.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/TestCollectionOrderer.cs @@ -10,7 +10,7 @@ namespace Telegram.Bot.Tests.Integ.Framework; public class TestCollectionOrderer : ITestCollectionOrderer { readonly string[] _orderedCollections = - { + [ // Tests that require user interaction: Constants.TestCollections.CallbackQuery, Constants.TestCollections.PrivateChatReplyMarkup, @@ -58,7 +58,7 @@ public class TestCollectionOrderer : ITestCollectionOrderer Constants.TestCollections.ChannelAdminBots, Constants.TestCollections.Exceptions2, Constants.TestCollections.SendCopyMessage - }; + ]; public IEnumerable OrderTestCollections(IEnumerable testCollections) { diff --git a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs index aedc8c9ad..d01ba853f 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/TestsFixture.cs @@ -5,6 +5,7 @@ using System.Threading; using System.Threading.Tasks; using Telegram.Bot.Args; +using Telegram.Bot.Requests; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; using Telegram.Bot.Types.ReplyMarkups; @@ -52,17 +53,21 @@ public void Dispose() await UpdateReceiver.DiscardNewUpdatesAsync(token); var passed = RunSummary.Total - RunSummary.Skipped - RunSummary.Failed; - await BotClient.SendTextMessageAsync( - chatId: SupergroupChat.Id, - text: string.Format( - Constants.TestExecutionResultMessageFormat, - RunSummary.Total, - passed, - RunSummary.Skipped, - RunSummary.Failed - ), - parseMode: ParseMode.Markdown, - cancellationToken: token + await BotClient.SendMessageAsync( + new() + { + ChatId = SupergroupChat.Id, + Text = string.Format( + Constants.TestExecutionResultMessageFormat, + RunSummary.Total, + passed, + RunSummary.Skipped, + RunSummary.Failed + ), + ParseMode = ParseMode.Markdown, + + }, + token ); }).GetAwaiter().GetResult(); } @@ -80,12 +85,15 @@ public async Task SendTestInstructionsAsync( : default; return await Ex.WithCancellation(async token => - await BotClient.SendTextMessageAsync( - chatId: chatId, - text: text, - parseMode: ParseMode.Markdown, - replyMarkup: replyMarkup, - cancellationToken: token + await BotClient.SendMessageAsync( + new() + { + ChatId = chatId, + Text = text, + ParseMode = ParseMode.Markdown, + ReplyMarkup = replyMarkup, + }, + token ) ); } @@ -132,20 +140,18 @@ bool IsMatch(Update u) => await UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); return chatType == ChatType.Channel - ? ((MessageOriginChannel)update.Message?.ForwardOrigin).Chat + ? ((MessageOriginChannel)update.Message?.ForwardOrigin)!.Chat : update.Message?.Chat; } public async Task GetChatFromAdminAsync() { - static bool IsMatch(Update u) => u - is { Message.Type: MessageType.Contact } - or { Message.NewChatMembers.Length: > 0 } - or { Message.ForwardOrigin: not null }; - await UpdateReceiver.DiscardNewUpdatesAsync(); - var update = await UpdateReceiver.GetUpdateAsync(IsMatch, updateTypes: [UpdateType.Message, UpdateType.ChatMember]); + var update = await UpdateReceiver.GetUpdateAsync( + IsMatch, + updateTypes: [UpdateType.Message, UpdateType.ChatMember] + ); await UpdateReceiver.DiscardNewUpdatesAsync(); @@ -157,7 +163,12 @@ static bool IsMatch(Update u) => u _ => throw new InvalidOperationException() }; - return await BotClient.GetChatAsync(userId!); + return await BotClient.GetChatAsync(new GetChatRequest { ChatId = userId! }); + + static bool IsMatch(Update u) => u + is { Message.Type: MessageType.Contact } + or { Message.NewChatMembers.Length: > 0 } + or { Message.ForwardOrigin: not null }; } async Task InitAsync() @@ -179,8 +190,8 @@ async Task InitAsync() var allowedUserNames = await Ex.WithCancellation( async token => { - BotUser = await BotClient.GetMeAsync(token); - await BotClient.DeleteWebhookAsync(cancellationToken: token); + BotUser = await BotClient.GetMeAsync(new(), token); + await BotClient.DeleteWebhookAsync(new DeleteWebhookRequest(), token); SupergroupChat = await FindSupergroupTestChatAsync(token); return await FindAllowedTesterUserNames(token); @@ -189,20 +200,23 @@ async Task InitAsync() UpdateReceiver = new(BotClient, allowedUserNames); - await Ex.WithCancellation(async token => await BotClient.SendTextMessageAsync( - chatId: SupergroupChat.Id, - text: $""" - ``` - Test execution is starting... - ``` - #testers - These users are allowed to interact with the bot: - - {UpdateReceiver.GetTesters()} - """, - parseMode: ParseMode.Markdown, - disableNotification: true, - cancellationToken: token + await Ex.WithCancellation(async token => await BotClient.SendMessageAsync( + new() + { + ChatId = SupergroupChat.Id, + Text = $""" + ``` + Test execution is starting... + ``` + #testers + These users are allowed to interact with the bot: + + {UpdateReceiver.GetTesters()} + """, + ParseMode = ParseMode.Markdown, + DisableNotification = true, + }, + token )); #if DEBUG @@ -235,12 +249,15 @@ Task SendNotificationToChatAsync( ? (InlineKeyboardMarkup)InlineKeyboardButton.WithSwitchInlineQueryCurrentChat("Start inline query") : default; - var task = BotClient.SendTextMessageAsync( - chatId: chatId, - text: text, - parseMode: ParseMode.Markdown, - replyMarkup: replyMarkup, - cancellationToken: cancellationToken + var task = BotClient.SendMessageAsync( + new() + { + ChatId = chatId, + Text = text, + ParseMode = ParseMode.Markdown, + ReplyMarkup = replyMarkup, + }, + cancellationToken ); return task; } @@ -248,7 +265,7 @@ Task SendNotificationToChatAsync( async Task FindSupergroupTestChatAsync(CancellationToken cancellationToken = default) { var supergroupChatId = Configuration.SuperGroupChatId; - return await BotClient.GetChatAsync(supergroupChatId, cancellationToken); + return await BotClient.GetChatAsync(new GetChatRequest {ChatId = supergroupChatId}, cancellationToken); } async Task> FindAllowedTesterUserNames(CancellationToken cancellationToken = default) @@ -259,7 +276,9 @@ async Task> FindAllowedTesterUserNames(CancellationToken can if (allowedUserNames.Length != 0) return allowedUserNames; // Assume all chat admins are allowed testers - var admins = await BotClient.GetChatAdministratorsAsync(SupergroupChat, cancellationToken); + var admins = await BotClient.GetChatAdministratorsAsync( + new GetChatAdministratorsRequest {ChatId = SupergroupChat}, cancellationToken + ); allowedUserNames = admins .Where(member => !member.User.IsBot) .Select(member => member.User.Username) @@ -303,7 +322,7 @@ async ValueTask OnMakingApiRequest( } } - multipartContent = [.. stringifiedFormContent]; + multipartContent = [..stringifiedFormContent]; } else { diff --git a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs index 3a7138d1f..14010064e 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/UpdateReceiver.cs @@ -203,7 +203,7 @@ static bool ShouldContinue( CancellationToken cancellationToken, (Update? update1, Update? update2) updates ) => - !cancellationToken.IsCancellationRequested && updates is not ({}, {}); + !cancellationToken.IsCancellationRequested && updates is not (not null, not null); } async Task GetOnlyAllowedUpdatesAsync( diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/AssemblyFixtureAttribute.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/AssemblyFixtureAttribute.cs index 14106f60c..78d9ef99d 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/AssemblyFixtureAttribute.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/AssemblyFixtureAttribute.cs @@ -3,12 +3,7 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] -public class AssemblyFixtureAttribute : Attribute +public class AssemblyFixtureAttribute(Type fixtureType) : Attribute { - public Type FixtureType { get; } - - public AssemblyFixtureAttribute(Type fixtureType) - { - FixtureType = fixtureType; - } + public Type FixtureType { get; } = fixtureType; } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/DelayedMessageBus.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/DelayedMessageBus.cs index 25e32d1c7..e6d0f3be1 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/DelayedMessageBus.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/DelayedMessageBus.cs @@ -9,13 +9,10 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; /// Used to capture messages to potentially be forwarded later. Messages are forwarded by /// disposing of the message bus. /// -public class DelayedMessageBus : IMessageBus +public class DelayedMessageBus(IMessageBus innerBus) : IMessageBus { - readonly IMessageBus _innerBus; readonly List _messages = new(); - public DelayedMessageBus(IMessageBus innerBus) => _innerBus = innerBus; - /// public bool QueueMessage(IMessageSinkMessage message) { @@ -34,7 +31,7 @@ public void Dispose() { foreach (var message in _messages) { - _innerBus.QueueMessage(message); + innerBus.QueueMessage(message); } } diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/RetryFactDiscoverer.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/RetryFactDiscoverer.cs index 381062259..842f1d874 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/RetryFactDiscoverer.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/RetryFactDiscoverer.cs @@ -4,15 +4,8 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; -public class RetryFactDiscoverer : IXunitTestCaseDiscoverer +public class RetryFactDiscoverer(IMessageSink diagnosticMessageSink) : IXunitTestCaseDiscoverer { - readonly IMessageSink _diagnosticMessageSink; - - public RetryFactDiscoverer(IMessageSink diagnosticMessageSink) - { - _diagnosticMessageSink = diagnosticMessageSink; - } - /// public IEnumerable Discover( ITestFrameworkDiscoveryOptions discoveryOptions, @@ -29,7 +22,7 @@ public IEnumerable Discover( .GetNamedArgument(nameof(OrderedFactAttribute.ExceptionTypeFullName)); var retryTestCase = new RetryTestCase( - _diagnosticMessageSink, + diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), testMethod, maxRetries, diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestAssemblyRunnerWithAssemblyFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestAssemblyRunnerWithAssemblyFixture.cs index c1c73418b..03871e23d 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestAssemblyRunnerWithAssemblyFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestAssemblyRunnerWithAssemblyFixture.cs @@ -9,24 +9,20 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; -public class XunitTestAssemblyRunnerWithAssemblyFixture : XunitTestAssemblyRunner +public class XunitTestAssemblyRunnerWithAssemblyFixture( + ITestAssembly testAssembly, + IEnumerable testCases, + IMessageSink diagnosticMessageSink, + IMessageSink executionMessageSink, + ITestFrameworkExecutionOptions executionOptions) + : XunitTestAssemblyRunner(testAssembly, + testCases, + diagnosticMessageSink, + executionMessageSink, + executionOptions) { readonly Dictionary _assemblyFixtureMappings = new(); - public XunitTestAssemblyRunnerWithAssemblyFixture( - ITestAssembly testAssembly, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageSink executionMessageSink, - ITestFrameworkExecutionOptions executionOptions) - : base( - testAssembly, - testCases, - diagnosticMessageSink, - executionMessageSink, - executionOptions) - { } - protected override async Task AfterTestAssemblyStartingAsync() { // Let everything initialize @@ -73,8 +69,8 @@ protected override async Task AfterTestAssemblyStartingAsync() } var fixture = ctor.Invoke(parameters.Length == 1 - ? new object[] { DiagnosticMessageSink } - : Array.Empty() + ? [DiagnosticMessageSink] + : [] ); _assemblyFixtureMappings[fixtureAttr.FixtureType] = fixture; @@ -118,4 +114,4 @@ protected override async Task RunTestCollectionAsync( return runSummary; } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestCollectionRunnerWithAssemblyFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestCollectionRunnerWithAssemblyFixture.cs index 77b5c6fbb..b5a53f584 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestCollectionRunnerWithAssemblyFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestCollectionRunnerWithAssemblyFixture.cs @@ -7,32 +7,24 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; -public class XunitTestCollectionRunnerWithAssemblyFixture : XunitTestCollectionRunner +public class XunitTestCollectionRunnerWithAssemblyFixture( + Dictionary assemblyFixtureMappings, + ITestCollection testCollection, + IEnumerable testCases, + IMessageSink diagnosticMessageSink, + IMessageBus messageBus, + ITestCaseOrderer testCaseOrderer, + ExceptionAggregator aggregator, + CancellationTokenSource cancellationTokenSource) + : XunitTestCollectionRunner(testCollection, + testCases, + diagnosticMessageSink, + messageBus, + testCaseOrderer, + aggregator, + cancellationTokenSource) { - readonly Dictionary _assemblyFixtureMappings; - readonly IMessageSink _diagnosticMessageSink; - - public XunitTestCollectionRunnerWithAssemblyFixture( - Dictionary assemblyFixtureMappings, - ITestCollection testCollection, - IEnumerable testCases, - IMessageSink diagnosticMessageSink, - IMessageBus messageBus, - ITestCaseOrderer testCaseOrderer, - ExceptionAggregator aggregator, - CancellationTokenSource cancellationTokenSource) - : base( - testCollection, - testCases, - diagnosticMessageSink, - messageBus, - testCaseOrderer, - aggregator, - cancellationTokenSource) - { - _assemblyFixtureMappings = assemblyFixtureMappings; - _diagnosticMessageSink = diagnosticMessageSink; - } + readonly IMessageSink _diagnosticMessageSink = diagnosticMessageSink; protected override async Task RunTestClassAsync( ITestClass testClass, @@ -41,7 +33,7 @@ protected override async Task RunTestClassAsync( { // Don't want to use .Concat + .ToDictionary because of the possibility of overriding types, // so instead we'll just let collection fixtures override assembly fixtures. - var combinedFixtures = new Dictionary(_assemblyFixtureMappings); + var combinedFixtures = new Dictionary(assemblyFixtureMappings); foreach (var (key, value) in CollectionFixtureMappings) { combinedFixtures[key] = value; diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkExecutorWithAssemblyFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkExecutorWithAssemblyFixture.cs index ec3026196..65180c015 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkExecutorWithAssemblyFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkExecutorWithAssemblyFixture.cs @@ -5,15 +5,12 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; -public class XunitTestFrameworkExecutorWithAssemblyFixture : XunitTestFrameworkExecutor +public class XunitTestFrameworkExecutorWithAssemblyFixture( + AssemblyName assemblyName, + ISourceInformationProvider sourceInformationProvider, + IMessageSink diagnosticMessageSink) + : XunitTestFrameworkExecutor(assemblyName, sourceInformationProvider, diagnosticMessageSink) { - public XunitTestFrameworkExecutorWithAssemblyFixture( - AssemblyName assemblyName, - ISourceInformationProvider sourceInformationProvider, - IMessageSink diagnosticMessageSink) - : base(assemblyName, sourceInformationProvider, diagnosticMessageSink) - { } - protected override async void RunTestCases( IEnumerable testCases, IMessageSink executionMessageSink, diff --git a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkWithAssemblyFixture.cs b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkWithAssemblyFixture.cs index 1ca3ea33e..6b82bde9f 100644 --- a/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkWithAssemblyFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Framework/XunitExtensions/XunitTestFrameworkWithAssemblyFixture.cs @@ -4,12 +4,8 @@ namespace Telegram.Bot.Tests.Integ.Framework.XunitExtensions; -public class XunitTestFrameworkWithAssemblyFixture : XunitTestFramework +public class XunitTestFrameworkWithAssemblyFixture(IMessageSink messageSink) : XunitTestFramework(messageSink) { - public XunitTestFrameworkWithAssemblyFixture(IMessageSink messageSink) - : base(messageSink) - { } - protected override ITestFrameworkExecutor CreateExecutor(AssemblyName assemblyName) => new XunitTestFrameworkExecutorWithAssemblyFixture( assemblyName, diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs index c2c2b37f6..51e092de4 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesExceptionTests.cs @@ -7,16 +7,9 @@ namespace Telegram.Bot.Tests.Integ.Games; [Collection(Constants.TestCollections.GameException)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class GamesExceptionTests +public class GamesExceptionTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public GamesExceptionTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should throw InvalidGameShortNameException")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendGame)] @@ -24,8 +17,11 @@ public async Task Should_Throw_InvalidGameShortNameException() { ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.SendGameAsync( - chatId: _fixture.SupergroupChat.Id, - gameShortName: "my game" + new() + { + ChatId = fixture.SupergroupChat.Id, + GameShortName = "my game", + } ) ); @@ -38,8 +34,11 @@ public async Task Should_Throw_InvalidGameShortNameException_2() { ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.SendGameAsync( - chatId: _fixture.SupergroupChat.Id, - gameShortName: "" + new() + { + ChatId = fixture.SupergroupChat.Id, + GameShortName = "", + } ) ); @@ -52,8 +51,11 @@ public async Task Should_Throw_InvalidGameShortNameException_3() { ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.SendGameAsync( - chatId: _fixture.SupergroupChat.Id, - gameShortName: "non_existing_game" + new() + { + ChatId = fixture.SupergroupChat.Id, + GameShortName = "non_existing_game", + } ) ); @@ -62,4 +64,4 @@ public async Task Should_Throw_InvalidGameShortNameException_3() // ToDo: Send game with markup & game button NOT as 1st: BUTTON_POS_INVALID // ToDo: Send game with markup & w/o game button: REPLY_MARKUP_GAME_EMPTY -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesFixture.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesFixture.cs index 11fa504b6..f28812974 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesFixture.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; @@ -31,12 +32,16 @@ public GamesFixture(TestsFixture fixture) { GameShortName = "game1"; - AddLifetime( - initialize: async () => + AddInitializer( + async () => { try { - await fixture.BotClient.SendGameAsync(fixture.SupergroupChat.Id, GameShortName); + await fixture.BotClient.SendGameAsync(new() + { + ChatId = fixture.SupergroupChat.Id, + GameShortName = GameShortName, + }); } catch (ApiRequestException e) { @@ -53,8 +58,8 @@ public GamesFixture(TestsFixture fixture) static async Task GetPlayerIdFromChatAdmins(TestsFixture testsFixture, long chatId) { - ChatMember[] admins = await testsFixture.BotClient.GetChatAdministratorsAsync(chatId); + ChatMember[] admins = await testsFixture.BotClient.GetChatAdministratorsAsync(new GetChatAdministratorsRequest { ChatId = chatId }); ChatMember player = admins[new Random(DateTime.Now.Millisecond).Next(admins.Length)]; return player.User; } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs index e396a6ddf..71f23783f 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -12,57 +13,50 @@ namespace Telegram.Bot.Tests.Integ.Games; [Collection(Constants.TestCollections.Games)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class GamesTests : IClassFixture +public class GamesTests(TestsFixture fixture, GamesFixture classFixture) : IClassFixture { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - readonly GamesFixture _classFixture; - - public GamesTests(TestsFixture fixture, GamesFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should answer inline query with a game")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_InlineQuery_With_Game() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update queryUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update queryUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "game"; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: queryUpdate.InlineQuery!.Id, - results: new InlineQueryResult[] + new() { - new InlineQueryResultGame - { - Id = resultId, - GameShortName = _classFixture.GameShortName, - } - }, - cacheTime: 0 + InlineQueryId = queryUpdate.InlineQuery!.Id, + Results = [ + new InlineQueryResultGame + { + Id = resultId, + GameShortName = classFixture.GameShortName, + } + ], + CacheTime = 0 + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Game ); Assert.Equal(MessageType.Game, messageUpdate?.Message?.Type); Assert.Equal(resultId, chosenResultUpdate?.ChosenInlineResult?.ResultId); Assert.NotNull(chosenResultUpdate?.ChosenInlineResult); + Assert.NotNull(chosenResultUpdate); Assert.Empty(chosenResultUpdate.ChosenInlineResult.Query); - _classFixture.InlineGameMessageId = chosenResultUpdate.ChosenInlineResult.InlineMessageId; + classFixture.InlineGameMessageId = chosenResultUpdate.ChosenInlineResult.InlineMessageId; } [OrderedFact("Should get game high score for inline message")] @@ -70,33 +64,39 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( public async Task Should_Get_High_Scores_Inline_Message() { GameHighScore[] highScores = await BotClient.GetGameHighScoresAsync( - userId: _classFixture.Player.Id, - inlineMessageId: _classFixture.InlineGameMessageId + new GetInlineGameHighScoresRequest + { + UserId = classFixture.Player.Id, + InlineMessageId = classFixture.InlineGameMessageId, + } ); Assert.All(highScores, _ => Assert.True(_.Position > 0)); Assert.All(highScores, _ => Assert.True(_.Score > 0)); Assert.All(highScores.Select(_ => _.User), Assert.NotNull); - _classFixture.HighScores = highScores; + classFixture.HighScores = highScores; } [OrderedFact("Should set game score for inline message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetGameScore)] public async Task Should_Set_Game_Score_Inline_Message() { - long playerId = _classFixture.Player.Id; - int oldScore = _classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score; + long playerId = classFixture.Player.Id; + int oldScore = classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score; int newScore = oldScore + 1 + new Random().Next(3); - await _fixture.SendTestInstructionsAsync( - $"Changing score from {oldScore} to {newScore} for {_classFixture.Player.Username!.Replace("_", @"\_")}." + await fixture.SendTestInstructionsAsync( + $"Changing score from {oldScore} to {newScore} for {classFixture.Player.Username!.Replace("_", @"\_")}." ); await BotClient.SetGameScoreAsync( - userId: playerId, - score: newScore, - inlineMessageId: _classFixture.InlineGameMessageId + new SetInlineGameScoreRequest + { + UserId = playerId, + Score = newScore, + InlineMessageId = classFixture.InlineGameMessageId, + } ); } @@ -104,17 +104,20 @@ await BotClient.SetGameScoreAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerCallbackQuery)] public async Task Should_Answer_CallbackQuery_With_Game_Url() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Click on any Play button on any of the game messages above 👆" ); - Update cqUpdate = await _fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(); + Update cqUpdate = await fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(); Assert.True(cqUpdate.CallbackQuery?.IsGameQuery); await BotClient.AnswerCallbackQueryAsync( - callbackQueryId: cqUpdate.CallbackQuery!.Id, - url: "https://tbot.xyz/lumber/" + new AnswerCallbackQueryRequest + { + CallbackQueryId = cqUpdate.CallbackQuery!.Id, + Url = "https://tbot.xyz/lumber/", + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs index 185644bff..dc84ebed1 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -11,27 +12,20 @@ namespace Telegram.Bot.Tests.Integ.Games; [Collection(Constants.TestCollections.Games2)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class GamesTests2 : IClassFixture +public class GamesTests2(TestsFixture fixture, GamesFixture classFixture) : IClassFixture { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - readonly GamesFixture _classFixture; - - public GamesTests2(TestsFixture fixture, GamesFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send game")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendGame)] public async Task Should_Send_Game() { Message gameMessage = await BotClient.SendGameAsync( - chatId: _fixture.SupergroupChat.Id, - gameShortName: _classFixture.GameShortName + new() + { + ChatId = fixture.SupergroupChat.Id, + GameShortName = classFixture.GameShortName, + } ); Assert.Equal(MessageType.Game, gameMessage.Type); @@ -45,7 +39,7 @@ public async Task Should_Send_Game() Assert.All(gameMessage.Game.Photo, p => Assert.True(p.Width > 80)); Assert.All(gameMessage.Game.Photo, p => Assert.True(p.Height > 40)); - _classFixture.GameMessage = gameMessage; + classFixture.GameMessage = gameMessage; } [OrderedFact("Should send game with a custom reply markup")] @@ -53,12 +47,14 @@ public async Task Should_Send_Game() public async Task Should_Send_Game_With_ReplyMarkup() { Message gameMessage = await BotClient.SendGameAsync( - chatId: _fixture.SupergroupChat.Id, - gameShortName: _classFixture.GameShortName, - replyMarkup: new[] + new() { - InlineKeyboardButton.WithCallBackGame(text: "Play"), - InlineKeyboardButton.WithCallbackData(textAndCallbackData: "Second button") + ChatId = fixture.SupergroupChat.Id, + GameShortName = classFixture.GameShortName, + ReplyMarkup = new([ + InlineKeyboardButton.WithCallBackGame(text: "Play"), + InlineKeyboardButton.WithCallbackData(textAndCallbackData: "Second button") + ]), } ); @@ -78,16 +74,19 @@ public async Task Should_Send_Game_With_ReplyMarkup() public async Task Should_Get_High_Scores() { GameHighScore[] highScores = await BotClient.GetGameHighScoresAsync( - userId: _classFixture.Player.Id, - chatId: _fixture.SupergroupChat.Id, - messageId: _classFixture.GameMessage.MessageId + new GetGameHighScoresRequest + { + UserId = classFixture.Player.Id, + ChatId = fixture.SupergroupChat.Id, + MessageId = classFixture.GameMessage.MessageId, + } ); Assert.All(highScores, hs => Assert.True(hs.Position > 0)); Assert.All(highScores, hs => Assert.True(hs.Score > 0)); Assert.All(highScores.Select(hs => hs.User), Assert.NotNull); - _classFixture.HighScores = highScores; + classFixture.HighScores = highScores; } [OrderedFact("Should set game score")] @@ -95,34 +94,42 @@ public async Task Should_Get_High_Scores() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetGameHighScores)] public async Task Should_Set_Game_Score() { - long playerId = _classFixture.Player.Id; + long playerId = classFixture.Player.Id; - bool playerAlreadyHasScore = _classFixture.HighScores + bool playerAlreadyHasScore = classFixture.HighScores .Any(highScore => highScore.User.Id == playerId); int oldScore = playerAlreadyHasScore - ? _classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score + ? classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score : 0; int newScore = oldScore + 1 + new Random().Next(3); - await _fixture.SendTestInstructionsAsync( - $"Changing score from {oldScore} to {newScore} for {_classFixture.Player.Username!.Replace("_", @"\_")}." + await fixture.SendTestInstructionsAsync( + $"Changing score from {oldScore} to {newScore} for {classFixture.Player.Username!.Replace("_", @"\_")}." ); Message gameMessage = await BotClient.SetGameScoreAsync( - userId: playerId, - score: newScore, - chatId: _fixture.SupergroupChat.Id, - messageId: _classFixture.GameMessage.MessageId + new SetGameScoreRequest + { + UserId = playerId, + Score = newScore, + ChatId = fixture.SupergroupChat.Id, + MessageId = classFixture.GameMessage.MessageId, + } ); - Assert.Equal(_classFixture.GameMessage.MessageId, gameMessage.MessageId); + Assert.Equal(classFixture.GameMessage.MessageId, gameMessage.MessageId); // update the high scores cache await Task.Delay(1_000); - _classFixture.HighScores = await BotClient.GetGameHighScoresAsync( - playerId, _fixture.SupergroupChat.Id, gameMessage.MessageId + classFixture.HighScores = await BotClient.GetGameHighScoresAsync( + new GetGameHighScoresRequest + { + UserId = playerId, + ChatId = fixture.SupergroupChat.Id, + MessageId = gameMessage.MessageId, + } ); } @@ -130,22 +137,25 @@ await _fixture.SendTestInstructionsAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetGameScore)] public async Task Should_Deduct_Game_Score() { - long playerId = _classFixture.Player.Id; - int oldScore = _classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score; + long playerId = classFixture.Player.Id; + int oldScore = classFixture.HighScores.Single(highScore => highScore.User.Id == playerId).Score; int newScore = oldScore - 1; - await _fixture.SendTestInstructionsAsync( - $"Changing score from {oldScore} to {newScore} for {_classFixture.Player.Username!.Replace("_", @"\_")}." + await fixture.SendTestInstructionsAsync( + $"Changing score from {oldScore} to {newScore} for {classFixture.Player.Username!.Replace("_", @"\_")}." ); Message gameMessage = await BotClient.SetGameScoreAsync( - userId: playerId, - score: newScore, - chatId: _fixture.SupergroupChat.Id, - messageId: _classFixture.GameMessage.MessageId, - force: true + new SetGameScoreRequest + { + UserId = playerId, + Score = newScore, + ChatId = fixture.SupergroupChat.Id, + MessageId = classFixture.GameMessage.MessageId, + Force = true, + } ); Assert.Equal(MessageType.Game, gameMessage.Type); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Getting Updates/GettingUpdatesTests.cs b/test/Telegram.Bot.Tests.Integ/Getting Updates/GettingUpdatesTests.cs index 70745c0b0..c866ef7c3 100644 --- a/test/Telegram.Bot.Tests.Integ/Getting Updates/GettingUpdatesTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Getting Updates/GettingUpdatesTests.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -9,13 +10,9 @@ namespace Telegram.Bot.Tests.Integ.Getting_Updates; [Collection(Constants.TestCollections.GettingUpdates)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class GettingUpdatesTests +public class GettingUpdatesTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public GettingUpdatesTests(TestsFixture fixture) => _fixture = fixture; + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should pass API Token test with valid token")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetMe)] @@ -59,7 +56,7 @@ public async Task Should_Test_Bad_BotToken() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetMe)] public async Task Should_Get_Bot_User() { - User botUser = await BotClient.GetMeAsync(); + User botUser = await BotClient.GetMeAsync(new GetMeRequest()); Assert.NotNull(botUser); Assert.NotNull(botUser.Username); diff --git a/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs b/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs index f4536dcfd..de6317b0a 100644 --- a/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Getting Updates/WebhookTests.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -26,7 +27,7 @@ public class WebhookTests(TestsFixture fixture) : IDisposable /// public void Dispose() { - BotClient.DeleteWebhookAsync() + BotClient.DeleteWebhookAsync(new DeleteWebhookRequest()) .GetAwaiter() .GetResult(); } @@ -35,7 +36,7 @@ public void Dispose() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetWebhook)] public async Task Should_Set_Webhook() { - await BotClient.SetWebhookAsync(url: "https://www.telegram.org/"); + await BotClient.SetWebhookAsync(new SetWebhookRequest { Url = "https://www.telegram.org/"}); } [OrderedFact("Should set webhook with options", Skip = "setWebhook requests are rate limited")] @@ -43,9 +44,12 @@ public async Task Should_Set_Webhook() public async Task Should_Set_Webhook_With_Options() { await BotClient.SetWebhookAsync( - url: "https://www.t.me/", - maxConnections: 5, - allowedUpdates: new[] { UpdateType.CallbackQuery, UpdateType.InlineQuery } + new SetWebhookRequest + { + Url = "https://www.t.me/", + MaxConnections = 5, + AllowedUpdates = [UpdateType.CallbackQuery, UpdateType.InlineQuery], + } ); } @@ -53,7 +57,7 @@ await BotClient.SetWebhookAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetWebhook)] public async Task Should_Delete_Webhook_Using_setWebhook() { - await BotClient.SetWebhookAsync(url: ""); + await BotClient.SetWebhookAsync(new SetWebhookRequest { Url = string.Empty }); } [OrderedFact("Should set webhook with self-signed certificate")] @@ -64,14 +68,17 @@ public async Task Should_Set_Webhook_With_SelfSigned_Cert() await using (Stream stream = File.OpenRead(Constants.PathToFile.Certificate.PublicKey)) { await BotClient.SetWebhookAsync( - url: "https://www.telegram.org/", - certificate: new InputFileStream(stream), - maxConnections: 3, - allowedUpdates: Array.Empty() // send all types of updates + new SetWebhookRequest + { + Url = "https://www.telegram.org/", + Certificate = InputFile.FromStream(stream), + MaxConnections = 3, + AllowedUpdates = Array.Empty(), // send all types of updates + } ); } - WebhookInfo info = await BotClient.GetWebhookInfoAsync(); + WebhookInfo info = await BotClient.GetWebhookInfoAsync(new GetWebhookInfoRequest()); Assert.Equal("https://www.telegram.org/", info.Url); Assert.True(info.HasCustomCertificate); @@ -83,14 +90,14 @@ await BotClient.SetWebhookAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteWebhook)] public async Task Should_Delete_Webhook() { - await BotClient.DeleteWebhookAsync(); + await BotClient.DeleteWebhookAsync(new DeleteWebhookRequest()); } [OrderedFact("Should get info of the deleted webhook")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetWebhookInfo)] public async Task Should_Get_Deleted_Webhook_Info() { - WebhookInfo info = await BotClient.GetWebhookInfoAsync(); + WebhookInfo info = await BotClient.GetWebhookInfoAsync(new GetWebhookInfoRequest()); Assert.Empty(info.Url); Assert.False(info.HasCustomCertificate); diff --git a/test/Telegram.Bot.Tests.Integ/Inline Keyboard/CallbackQueryTests.cs b/test/Telegram.Bot.Tests.Integ/Inline Keyboard/CallbackQueryTests.cs index 2eec645db..b20eb53c9 100644 --- a/test/Telegram.Bot.Tests.Integ/Inline Keyboard/CallbackQueryTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Inline Keyboard/CallbackQueryTests.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Newtonsoft.Json.Linq; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -13,16 +14,9 @@ namespace Telegram.Bot.Tests.Integ.Interactive; [Collection(Constants.TestCollections.CallbackQuery)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class CallbackQueryTests +public class CallbackQueryTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public CallbackQueryTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should receive and answer callback query result with a notification")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] @@ -31,22 +25,25 @@ public async Task Should_Answer_With_Notification() { string callbackQueryData = 'a' + new Random().Next(5_000).ToString(); - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Please click on *OK* button.", - parseMode: ParseMode.Markdown, - replyMarkup: new InlineKeyboardMarkup(new[] + Message message = await BotClient.SendMessageAsync( + new() { - InlineKeyboardButton.WithCallbackData("OK", callbackQueryData) - }) + ChatId = fixture.SupergroupChat.Id, + Text = "Please click on *OK* button.", + ParseMode = ParseMode.Markdown, + ReplyMarkup = new InlineKeyboardMarkup([InlineKeyboardButton.WithCallbackData("OK", callbackQueryData)]), + } ); - Update responseUpdate = await _fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(message.MessageId); + Update responseUpdate = await fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(message.MessageId); CallbackQuery callbackQuery = responseUpdate.CallbackQuery!; await BotClient.AnswerCallbackQueryAsync( - callbackQueryId: callbackQuery!.Id, - text: "You clicked on OK" + new AnswerCallbackQueryRequest + { + CallbackQueryId = callbackQuery!.Id, + Text = "You clicked on OK", + } ); Assert.Equal(UpdateType.CallbackQuery, responseUpdate.Type); @@ -70,22 +67,28 @@ public async Task Should_Answer_With_Alert() { string callbackQueryData = $"b{new Random().Next(5_000)}"; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Please click on *Notify* button.", - parseMode: ParseMode.Markdown, - replyMarkup: new InlineKeyboardMarkup( - InlineKeyboardButton.WithCallbackData("Notify", callbackQueryData) - ) + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "Please click on *Notify* button.", + ParseMode = ParseMode.Markdown, + ReplyMarkup = new InlineKeyboardMarkup( + InlineKeyboardButton.WithCallbackData("Notify", callbackQueryData) + ), + } ); - Update responseUpdate = await _fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(message.MessageId); + Update responseUpdate = await fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(message.MessageId); CallbackQuery callbackQuery = responseUpdate.CallbackQuery!; await BotClient.AnswerCallbackQueryAsync( - callbackQueryId: responseUpdate.CallbackQuery!.Id, - text: "Got it!", - showAlert: true + new AnswerCallbackQueryRequest + { + CallbackQueryId = responseUpdate.CallbackQuery!.Id, + Text = "Got it!", + ShowAlert = true, + } ); Assert.Equal(UpdateType.CallbackQuery, responseUpdate.Type); @@ -97,8 +100,9 @@ await BotClient.AnswerCallbackQueryAsync( Assert.False(callbackQuery.From.IsBot); Assert.NotNull(callbackQuery.From.Username); Assert.NotEmpty(callbackQuery.From.Username); + Assert.NotNull(callbackQuery.Message); Assert.True(JToken.DeepEquals( JToken.FromObject(message), JToken.FromObject(callbackQuery.Message) )); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs index 18afa6074..10e492213 100644 --- a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -14,31 +15,26 @@ namespace Telegram.Bot.Tests.Integ.Inline_Mode; [Collection(Constants.TestCollections.InlineQuery)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class InlineQueryTests +public class InlineQueryTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public InlineQueryTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should answer inline query with an article")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Article() { - await _fixture.SendTestInstructionsAsync( - "1. Start an inline query\n" + - "2. Wait for bot to answer it\n" + - "3. Choose the answer", + await fixture.SendTestInstructionsAsync( + """ + 1. Start an inline query + 2. Wait for bot to answer it + 3. Choose the answer + """, startInlineQuery: true ); // Wait for tester to start an inline query // This looks for an Update having a value on "inline_query" field - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); // Prepare results of the query InlineQueryResult[] results = @@ -54,17 +50,20 @@ await _fixture.SendTestInstructionsAsync( // Answer the query await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); // Wait for tester to choose a result and send it(as a message) to the chat ( Update messageUpdate, Update chosenResultUpdate - ) = await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + ) = await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Text ); @@ -77,14 +76,16 @@ Update chosenResultUpdate [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Get_Message_From_Inline_Query_With_ViaBot() { - await _fixture.SendTestInstructionsAsync( - "1. Start an inline query\n" + - "2. Wait for bot to answer it\n" + - "3. Choose the answer", + await fixture.SendTestInstructionsAsync( + """ + 1. Start an inline query + 2. Wait for bot to answer it + 3. Choose the answer + """, startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); InlineQueryResult[] results = [ @@ -98,12 +99,15 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); - Update messageUpdate = await _fixture.UpdateReceiver.GetUpdateAsync( + Update messageUpdate = await fixture.UpdateReceiver.GetUpdateAsync( predicate: update => update.Message!.ViaBot is not null, updateTypes: [UpdateType.Message] ); @@ -111,19 +115,19 @@ await BotClient.AnswerInlineQueryAsync( Assert.NotNull(messageUpdate.Message); Assert.Equal(MessageType.Text, messageUpdate.Message.Type); Assert.NotNull(messageUpdate.Message.ViaBot); - Assert.Equal(_fixture.BotUser.Id, messageUpdate.Message.ViaBot.Id); + Assert.Equal(fixture.BotUser.Id, messageUpdate.Message.ViaBot.Id); } [OrderedFact("Should answer inline query with a contact")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Contact() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "contact:john-doe"; InlineQueryResult[] results = @@ -138,14 +142,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Contact ); Update resultUpdate = chosenResultUpdate; @@ -159,12 +166,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Location() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "location:hobitton"; InlineQueryResult[] results = @@ -179,14 +186,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Location ); Update resultUpdate = chosenResultUpdate; @@ -200,12 +210,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Venue() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "venue:hobbiton"; InlineQueryResult[] results = @@ -221,14 +231,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Venue ); Update resultUpdate = chosenResultUpdate; @@ -242,12 +255,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Photo() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "photo:rainbow-girl"; const string url = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg"; @@ -270,8 +283,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Photo ); Update resultUpdate = chosenResultUpdate; @@ -290,14 +303,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Photo() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Apes)) { photoMessage = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat, - photo: new InputFileStream(stream), + chatId: fixture.SupergroupChat, + photo: InputFile.FromStream(stream), replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton .WithSwitchInlineQueryCurrentChat("Start inline query") ); } - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "photo:apes"; const string caption = "Apes smoking shisha"; @@ -318,8 +331,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Photo ); Update resultUpdate = chosenResultUpdate; @@ -334,12 +347,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Video() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "sunset_video"; InlineQueryResult[] results = @@ -362,8 +375,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Video ); Update resultUpdate = chosenResultUpdate; @@ -379,12 +392,12 @@ public async Task Should_Answer_Inline_Query_With_HTML_Video() { // ToDo exception when input_message_content not specified. Bad Request: SEND_MESSAGE_MEDIA_INVALID - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "youtube_video"; InlineQueryResult[] results = @@ -411,8 +424,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Text ); Update resultUpdate = chosenResultUpdate; @@ -428,13 +441,13 @@ public async Task Should_Answer_Inline_Query_With_Cached_Video() { // Video from https://pixabay.com/en/videos/fireworks-rocket-new-year-s-eve-7122/ Message videoMessage = await BotClient.SendVideoAsync( - chatId: _fixture.SupergroupChat, - video: new InputFileUrl("https://pixabay.com/en/videos/download/video-7122_medium.mp4"), + chatId: fixture.SupergroupChat, + video: InputFile.FromUri("https://pixabay.com/en/videos/download/video-7122_medium.mp4"), replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton .WithSwitchInlineQueryCurrentChat("Start inline query") ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "fireworks_video"; InlineQueryResult[] results = @@ -455,8 +468,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Video ); Update resultUpdate = chosenResultUpdate; @@ -470,12 +483,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Audio() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "audio_result"; InlineQueryResult[] results = @@ -497,8 +510,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Audio ); Update resultUpdate = chosenResultUpdate; @@ -517,8 +530,8 @@ public async Task Should_Answer_Inline_Query_With_Cached_Audio() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.CantinaRagMp3)) { audioMessage = await BotClient.SendAudioAsync( - chatId: _fixture.SupergroupChat, - audio: new InputFileStream(stream), + chatId: fixture.SupergroupChat, + audio: InputFile.FromStream(stream), performer: "Jackson F. Smith", duration: 201, replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton @@ -526,7 +539,7 @@ public async Task Should_Answer_Inline_Query_With_Cached_Audio() ); } - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "audio_result"; InlineQueryResult[] results = @@ -546,8 +559,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Audio ); Update resultUpdate = chosenResultUpdate; @@ -561,12 +574,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Voice() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "voice_result"; InlineQueryResult[] results = @@ -588,8 +601,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Voice ); Update resultUpdate = chosenResultUpdate; @@ -607,15 +620,15 @@ public async Task Should_Answer_Inline_Query_With_Cached_Voice() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.TestOgg)) { voiceMessage = await BotClient.SendVoiceAsync( - chatId: _fixture.SupergroupChat, - voice: new InputFileStream(stream), + chatId: fixture.SupergroupChat, + voice: InputFile.FromStream(stream), duration: 24, replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton .WithSwitchInlineQueryCurrentChat("Start inline query") ); } - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "voice_result"; InlineQueryResult[] results = @@ -635,8 +648,8 @@ await BotClient.AnswerInlineQueryAsync( ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Voice ); Update resultUpdate = chosenResultUpdate; @@ -650,12 +663,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Document() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "document_result"; InlineQueryResult[] results = @@ -672,14 +685,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Document ); Update resultUpdate = chosenResultUpdate; @@ -697,14 +713,17 @@ public async Task Should_Answer_Inline_Query_With_Cached_Document() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Documents.Hamlet)) { documentMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileStream(stream), - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query") + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromStream(stream), + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } ); } - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "document_result"; InlineQueryResult[] results = @@ -720,14 +739,17 @@ public async Task Should_Answer_Inline_Query_With_Cached_Document() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Document ); Update resultUpdate = chosenResultUpdate; @@ -741,12 +763,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Gif() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "gif_result"; InlineQueryResult[] results = @@ -766,14 +788,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Animation ); Update resultUpdate = chosenResultUpdate; @@ -788,12 +813,16 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( public async Task Should_Answer_Inline_Query_With_Cached_Gif() { Message gifMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileUrl("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"), - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query")); + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"), + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } + ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "gif_result"; InlineQueryResult[] results = @@ -807,14 +836,17 @@ public async Task Should_Answer_Inline_Query_With_Cached_Gif() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Animation ); Update resultUpdate = chosenResultUpdate; @@ -828,12 +860,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Mpeg4Gif() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "mpeg4_gif_result"; InlineQueryResult[] results = @@ -848,14 +880,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Video ); Update resultUpdate = chosenResultUpdate; @@ -870,12 +905,16 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( public async Task Should_Answer_Inline_Query_With_Cached_Mpeg4Gif() { Message gifMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileUrl("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"), - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query")); + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"), + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } + ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "mpeg4_gif_result"; InlineQueryResult[] results = @@ -889,14 +928,17 @@ public async Task Should_Answer_Inline_Query_With_Cached_Mpeg4Gif() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Animation ); Update resultUpdate = chosenResultUpdate; @@ -911,14 +953,14 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Cached_Sticker() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); - StickerSet stickerSet = await BotClient.GetStickerSetAsync("EvilMinds"); + StickerSet stickerSet = await BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = "EvilMinds"}); const string resultId = "sticker_result"; InlineQueryResult[] results = @@ -931,14 +973,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Sticker ); Update resultUpdate = chosenResultUpdate; @@ -952,12 +997,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Answer_Inline_Query_With_Photo_With_Markdown_Encoded_Caption() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); const string resultId = "photo:rainbow-girl-caption"; const string url = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg"; @@ -975,14 +1020,17 @@ await _fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Photo ); @@ -999,12 +1047,12 @@ await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Throw_Exception_When_Answering_Late() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Write an inline query that I'll never answer!", startInlineQuery: true ); - Update queryUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update queryUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); InlineQueryResult[] results = [ @@ -1021,9 +1069,12 @@ await _fixture.SendTestInstructionsAsync( ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.AnswerInlineQueryAsync( - inlineQueryId: queryUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = queryUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ) ); diff --git a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs index 48213b702..c5ab0b6cf 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs +++ b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.InlineQueryResults; @@ -12,73 +13,69 @@ namespace Telegram.Bot.Tests.Integ.Locations; [Collection(Constants.TestCollections.InlineMessageLiveLocation)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class InlineMessageLiveLocationTests : IClassFixture +public class InlineMessageLiveLocationTests(TestsFixture fixture, InlineMessageLiveLocationTests.Fixture classFixture) + : IClassFixture { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly Fixture _classFixture; - - readonly TestsFixture _fixture; - - public InlineMessageLiveLocationTests(TestsFixture fixture, Fixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should answer inline query with a location result")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageLiveLocation)] public async Task Should_Answer_Inline_Query_With_Location() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Staring the inline query with this message...", startInlineQuery: true ); - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); string callbackQueryData = $"edit-location{new Random().Next(1_000)}"; Location newYork = new() { Latitude = 40.7128f, Longitude = -74.0060f }; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - cacheTime: 0, - results: new[] + new() { - new InlineQueryResultLocation - { - Id = "live-location", - Latitude = newYork.Latitude, - Longitude = newYork.Longitude, - Title = "Live Locations Test", - LivePeriod = 60, - ReplyMarkup = InlineKeyboardButton.WithCallbackData("Start live locations", callbackQueryData) - } + InlineQueryId = iqUpdate.InlineQuery!.Id, + CacheTime = 0, + Results = [ + new InlineQueryResultLocation + { + Id = "live-location", + Latitude = newYork.Latitude, + Longitude = newYork.Longitude, + Title = "Live Locations Test", + LivePeriod = 60, + ReplyMarkup = InlineKeyboardButton.WithCallbackData("Start live locations", callbackQueryData) + } + ], } ); - _classFixture.CallbackQueryData = callbackQueryData; + classFixture.CallbackQueryData = callbackQueryData; } [OrderedFact("Should edit live location of previously sent inline message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageLiveLocation)] public async Task Should_Edit_Inline_Message_Live_Location() { - await _fixture.SendTestInstructionsAsync("Click on location message's button to edit the location"); + await fixture.SendTestInstructionsAsync("Click on location message's button to edit the location"); - Update cqUpdate = await _fixture.UpdateReceiver - .GetCallbackQueryUpdateAsync(data: _classFixture.CallbackQueryData); + Update cqUpdate = await fixture.UpdateReceiver + .GetCallbackQueryUpdateAsync(data: classFixture.CallbackQueryData); Location beijing = new() { Latitude = 39.9042f, Longitude = 116.4074f }; await BotClient.EditMessageLiveLocationAsync( - inlineMessageId: cqUpdate.CallbackQuery!.InlineMessageId!, - latitude: beijing.Latitude, - longitude: beijing.Longitude, - replyMarkup: InlineKeyboardMarkup.Empty() + new EditInlineMessageLiveLocationRequest + { + InlineMessageId = cqUpdate.CallbackQuery!.InlineMessageId!, + Latitude = beijing.Latitude, + Longitude = beijing.Longitude, + ReplyMarkup = InlineKeyboardMarkup.Empty(), + } ); - _classFixture.InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId; + classFixture.InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId; } [OrderedFact("Should stop live locations of previously sent inline message")] @@ -86,7 +83,10 @@ await BotClient.EditMessageLiveLocationAsync( public async Task Should_Stop_Inline_Message_Live_Location() { await BotClient.StopMessageLiveLocationAsync( - inlineMessageId: _classFixture.InlineMessageId + new StopInlineMessageLiveLocationRequest + { + InlineMessageId = classFixture.InlineMessageId, + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs b/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs index af3e32f8e..c31226935 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; @@ -10,24 +11,15 @@ namespace Telegram.Bot.Tests.Integ.Locations; [Collection(Constants.TestCollections.LiveLocation)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class LiveLocationTests : IClassFixture> +public class LiveLocationTests(TestsFixture fixture, EntityFixture classFixture) + : IClassFixture> { - ITelegramBotClient BotClient => _fixture.BotClient; + ITelegramBotClient BotClient => fixture.BotClient; Message LocationMessage { - get => _classFixture.Entity; - set => _classFixture.Entity = value; - } - - readonly TestsFixture _fixture; - - readonly EntityFixture _classFixture; - - public LiveLocationTests(TestsFixture fixture, EntityFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; + get => classFixture.Entity; + set => classFixture.Entity = value; } [OrderedFact("Should send a location with live period to update")] @@ -38,10 +30,13 @@ public async Task Should_Send_Live_Location() const float lonBerlin = 13.4050f; Message message = await BotClient.SendLocationAsync( - chatId: _fixture.SupergroupChat.Id, - latitude: latBerlin, - longitude: lonBerlin, - livePeriod: 60 + new() + { + ChatId = fixture.SupergroupChat.Id, + Latitude = latBerlin, + Longitude = lonBerlin, + LivePeriod = 60, + } ); Assert.Equal(MessageType.Location, message.Type); @@ -55,11 +50,11 @@ public async Task Should_Send_Live_Location() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageLiveLocation)] public async Task Should_Update_Live_Location() { - Location[] locations = { - new Location { Latitude = 43.6532f, Longitude = -79.3832f }, // Toronto - new Location { Latitude = 59.9343f, Longitude = 30.3351f }, // Saint Petersburg - new Location { Latitude = 35.6892f, Longitude = 51.3890f }, // Tehran - }; + Location[] locations = [ + new() { Latitude = 43.6532f, Longitude = -79.3832f }, // Toronto + new() { Latitude = 59.9343f, Longitude = 30.3351f }, // Saint Petersburg + new() { Latitude = 35.6892f, Longitude = 51.3890f } // Tehran + ]; Message editedMessage = default; foreach (Location newLocation in locations) @@ -67,10 +62,13 @@ public async Task Should_Update_Live_Location() await Task.Delay(1_500); editedMessage = await BotClient.EditMessageLiveLocationAsync( - chatId: LocationMessage.Chat.Id, - messageId: LocationMessage.MessageId, - latitude: newLocation.Latitude, - longitude: newLocation.Longitude + new EditMessageLiveLocationRequest + { + ChatId = LocationMessage.Chat.Id, + MessageId = LocationMessage.MessageId, + Latitude = newLocation.Latitude, + Longitude = newLocation.Longitude, + } ); Assert.Equal(MessageType.Location, editedMessage.Type); @@ -87,8 +85,11 @@ public async Task Should_Update_Live_Location() public async Task Should_Stop_Live_Location() { Message message = await BotClient.StopMessageLiveLocationAsync( - chatId: LocationMessage.Chat, - messageId: LocationMessage.MessageId + new StopMessageLiveLocationRequest + { + ChatId = LocationMessage.Chat, + MessageId = LocationMessage.MessageId, + } ); Assert.Equal(LocationMessage.MessageId, message.MessageId); @@ -98,4 +99,4 @@ public async Task Should_Stop_Live_Location() Assert.Equal(LocationMessage.Location.Latitude, message.Location.Latitude); Assert.Equal(LocationMessage.Location.Longitude, message.Location.Longitude); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs index 963ad0671..c281a3f8a 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotCommandsTests.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -8,24 +9,18 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.BotCommands)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class BotCommandsTests: IAsyncLifetime +public class BotCommandsTests(TestsFixture fixture) : IAsyncLifetime { - readonly TestsFixture _fixture; BotCommandScope _scope; - ITelegramBotClient BotClient => _fixture.BotClient; - - public BotCommandsTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should set a new bot command list")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyCommands)] public async Task Should_Set_New_Bot_Command_List() { BotCommand[] commands = - { + [ new() { Command = "start", @@ -35,14 +30,17 @@ public async Task Should_Set_New_Bot_Command_List() { Command = "help", Description = "Help command" - }, - }; + } + ]; _scope = BotCommandScope.Default(); await BotClient.SetMyCommandsAsync( - commands: commands, - scope: _scope + new SetMyCommandsRequest + { + Commands = commands, + Scope = _scope, + } ); } @@ -66,14 +64,17 @@ public async Task Should_Get_Set_Bot_Commands() _scope = BotCommandScope.Default(); - await _fixture.BotClient.SetMyCommandsAsync( - commands: commands, - scope: _scope + await fixture.BotClient.SetMyCommandsAsync( + new SetMyCommandsRequest + { + Commands = commands, + Scope = _scope, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotCommand[] currentCommands = await _fixture.BotClient.GetMyCommandsAsync(); + BotCommand[] currentCommands = await fixture.BotClient.GetMyCommandsAsync(new GetMyCommandsRequest()); Assert.Equal(2, currentCommands.Length); Asserts.JsonEquals(commands, currentCommands); @@ -85,7 +86,7 @@ await _fixture.BotClient.SetMyCommandsAsync( public async Task Should_Delete_Bot_Commands() { BotCommand[] commands = - { + [ new() { Command = "start", @@ -95,26 +96,29 @@ public async Task Should_Delete_Bot_Commands() { Command = "help", Description = "Help command" - }, - }; + } + ]; _scope = BotCommandScope.Default(); await BotClient.SetMyCommandsAsync( - commands: commands, - scope: _scope + new SetMyCommandsRequest + { + Commands = commands, + Scope = _scope, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotCommand[] setCommands = await BotClient.GetMyCommandsAsync(); + BotCommand[] setCommands = await BotClient.GetMyCommandsAsync(new GetMyCommandsRequest()); Assert.NotNull(setCommands); Asserts.JsonEquals(commands, setCommands); - await BotClient.DeleteMyCommandsAsync(scope: _scope); + await BotClient.DeleteMyCommandsAsync(new DeleteMyCommandsRequest { Scope = _scope}); - BotCommand[] currentCommands = await BotClient.GetMyCommandsAsync(scope: _scope); + BotCommand[] currentCommands = await BotClient.GetMyCommandsAsync(new GetMyCommandsRequest { Scope = _scope }); Assert.NotNull(currentCommands); Assert.Empty(currentCommands); @@ -125,7 +129,7 @@ await BotClient.SetMyCommandsAsync( public async Task Should_Set_Group_Scoped_Commands() { BotCommand[] commands = - { + [ new() { Command = "start", @@ -135,23 +139,27 @@ public async Task Should_Set_Group_Scoped_Commands() { Command = "help", Description = "Help command" - }, - }; + } + ]; _scope = BotCommandScope.AllGroupChats(); await BotClient.SetMyCommandsAsync( - commands: commands, - scope: _scope + new SetMyCommandsRequest + { + Commands = commands, + Scope = _scope, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotCommand[] newCommands = await BotClient.GetMyCommandsAsync(scope: _scope); + BotCommand[] newCommands = await BotClient.GetMyCommandsAsync(new GetMyCommandsRequest { Scope = _scope }); Asserts.JsonEquals(commands, newCommands); } public Task InitializeAsync() => Task.CompletedTask; - public async Task DisposeAsync() => await _fixture.BotClient.DeleteMyCommandsAsync(scope: _scope); + public async Task DisposeAsync() => + await fixture.BotClient.DeleteMyCommandsAsync(new DeleteMyCommandsRequest { Scope = _scope }); } diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs index 69de8c442..9c1ef8926 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -8,17 +9,11 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.BotDescription)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class BotDescriptionTests: IAsyncLifetime +public class BotDescriptionTests(TestsFixture fixture) : IAsyncLifetime { - readonly TestsFixture _fixture; string _languageCode; - ITelegramBotClient BotClient => _fixture.BotClient; - - public BotDescriptionTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should set a new bot description")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyDescription)] @@ -43,7 +38,7 @@ await BotClient.SetMyDescriptionAsync( await Task.Delay(TimeSpan.FromSeconds(10)); - BotDescription currentDescription = await _fixture.BotClient.GetMyDescriptionAsync(); + BotDescription currentDescription = await fixture.BotClient.GetMyDescriptionAsync(new GetMyDescriptionRequest()); Assert.NotNull(currentDescription); Assert.Equal(description, currentDescription.Description); @@ -59,7 +54,7 @@ await BotClient.SetMyDescriptionAsync( description: description ); - BotDescription setDescription = await _fixture.BotClient.GetMyDescriptionAsync(); + BotDescription setDescription = await fixture.BotClient.GetMyDescriptionAsync(new GetMyDescriptionRequest()); Assert.NotNull(setDescription); Assert.Equal(description, setDescription.Description); @@ -70,7 +65,7 @@ await BotClient.SetMyDescriptionAsync( await Task.Delay(TimeSpan.FromSeconds(10)); - BotDescription currentDescription = await _fixture.BotClient.GetMyDescriptionAsync(); + BotDescription currentDescription = await fixture.BotClient.GetMyDescriptionAsync(new GetMyDescriptionRequest()); Assert.NotNull(currentDescription.Description); Assert.Empty(currentDescription.Description); @@ -91,7 +86,7 @@ await BotClient.SetMyDescriptionAsync( await Task.Delay(TimeSpan.FromSeconds(10)); - BotDescription newDescription = await _fixture.BotClient.GetMyDescriptionAsync(languageCode: _languageCode); + BotDescription newDescription = await fixture.BotClient.GetMyDescriptionAsync(languageCode: _languageCode); Assert.NotNull(newDescription); Assert.Equal(description, newDescription.Description); diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs index 6c15d22b3..ecc632b1a 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotShortDescriptionTests.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -10,10 +11,9 @@ namespace Telegram.Bot.Tests.Integ.Other; [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] public class BotShortDescriptionTests(TestsFixture fixture) : IAsyncLifetime { - readonly TestsFixture _fixture = fixture; string _languageCode; - ITelegramBotClient BotClient => _fixture.BotClient; + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should set a new bot short description")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SetMyShortDescription)] @@ -22,7 +22,7 @@ public async Task Should_Set_New_Bot__Short_Description() const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( - shortDescription: shortDescription + new SetMyShortDescriptionRequest { ShortDescription = shortDescription } ); } @@ -33,12 +33,12 @@ public async Task Should_Get_Set_Bot_Short_Description() const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( - shortDescription: shortDescription + new SetMyShortDescriptionRequest { ShortDescription = shortDescription } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotShortDescription currentShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); + BotShortDescription currentShortDescription = await fixture.BotClient.GetMyShortDescriptionAsync(new GetMyShortDescriptionRequest()); Assert.NotNull(currentShortDescription); Assert.Equal(shortDescription, currentShortDescription.ShortDescription); @@ -51,22 +51,22 @@ public async Task Should_Delete_Bot_Short_Description() const string shortDescription = "Test bot short description"; await BotClient.SetMyShortDescriptionAsync( - shortDescription: shortDescription + new SetMyShortDescriptionRequest { ShortDescription = shortDescription } ); - BotShortDescription setShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); + BotShortDescription setShortDescription = await fixture.BotClient.GetMyShortDescriptionAsync(new GetMyShortDescriptionRequest()); Assert.NotNull(setShortDescription); Assert.Equal(shortDescription, setShortDescription.ShortDescription); await BotClient.SetMyShortDescriptionAsync( - shortDescription: "" + new SetMyShortDescriptionRequest { ShortDescription = "" } ); // Test fails receiving old description without a delay await Task.Delay(TimeSpan.FromSeconds(20)); - BotShortDescription currentShortDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(); + BotShortDescription currentShortDescription = await fixture.BotClient.GetMyShortDescriptionAsync(new GetMyShortDescriptionRequest()); Assert.NotNull(currentShortDescription.ShortDescription); Assert.Empty(currentShortDescription.ShortDescription); @@ -81,13 +81,18 @@ public async Task Should_Set_Short_Description_With_Language_Code_Area() _languageCode = "ru"; await BotClient.SetMyShortDescriptionAsync( - shortDescription: shortDescription, - languageCode: _languageCode + new SetMyShortDescriptionRequest + { + ShortDescription = shortDescription, + LanguageCode = _languageCode, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotShortDescription newDescription = await _fixture.BotClient.GetMyShortDescriptionAsync(languageCode: _languageCode); + BotShortDescription newDescription = await fixture.BotClient.GetMyShortDescriptionAsync( + new GetMyShortDescriptionRequest {LanguageCode = _languageCode} + ); Assert.NotNull(newDescription); Assert.Equal(shortDescription, newDescription.ShortDescription); @@ -98,12 +103,15 @@ await BotClient.SetMyShortDescriptionAsync( public async Task DisposeAsync() { await BotClient.SetMyShortDescriptionAsync( - shortDescription: "" - ); + new SetMyShortDescriptionRequest { ShortDescription = "" + }); await BotClient.SetMyShortDescriptionAsync( - shortDescription: "", - languageCode: _languageCode + new SetMyShortDescriptionRequest + { + ShortDescription = "", + LanguageCode = _languageCode + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs b/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs index 114dc88ef..eb5a6710c 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs @@ -10,18 +10,15 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.ChatInfo)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class ChatInfoTests +public class ChatInfoTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - readonly TestsFixture _fixture; - - public ChatInfoTests(TestsFixture fixture) => _fixture = fixture; + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should get supergroup chat info")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetChat)] public async Task Should_Get_Supergroup_Chat() { - Chat supergroupChat = _fixture.SupergroupChat; + Chat supergroupChat = fixture.SupergroupChat; Chat chat = await BotClient.GetChatAsync( chatId: supergroupChat.Id @@ -48,8 +45,8 @@ public async Task Should_Get_Supergroup_Chat() public async Task Should_Get_Bot_Chat_Member() { ChatMember memberBot = await BotClient.GetChatMemberAsync( - chatId: _fixture.SupergroupChat.Id, - userId: _fixture.BotUser.Id + chatId: fixture.SupergroupChat.Id, + userId: fixture.BotUser.Id ); Assert.Equal(ChatMemberStatus.Administrator, memberBot.Status); @@ -66,7 +63,7 @@ public async Task Should_Get_Bot_Chat_Member() Assert.Null(administrator.CanPostMessages); Assert.Null(administrator.CanEditMessages); - Asserts.UsersEqual(_fixture.BotUser, memberBot.User); + Asserts.UsersEqual(fixture.BotUser, memberBot.User); } [OrderedFact("Should get supergroup chat administrators")] @@ -74,7 +71,7 @@ public async Task Should_Get_Bot_Chat_Member() public async Task Should_Get_Chat_Admins() { ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync( - chatId: _fixture.SupergroupChat.Id + chatId: fixture.SupergroupChat.Id ); ChatMember memberCreator = Assert.Single(chatAdmins, _ => _.Status == ChatMemberStatus.Creator); @@ -84,7 +81,7 @@ public async Task Should_Get_Chat_Admins() Debug.Assert(memberBot != null); Assert.True(2 <= chatAdmins.Length); // at least, Bot and the Creator - Asserts.UsersEqual(_fixture.BotUser, memberBot.User); + Asserts.UsersEqual(fixture.BotUser, memberBot.User); } [OrderedFact("Should get private chat info")] @@ -97,7 +94,7 @@ public async Task Should_Get_Private_Chat() /* In order to have a private chat id, take the Creator of supergroup and use his User ID because * for a regular user, "User ID" is the same number as "Private Chat ID". */ - ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync(_fixture.SupergroupChat); + ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync(fixture.SupergroupChat); privateChatId = chatAdmins .Single(member => member.Status == ChatMemberStatus.Creator) .User.Id; @@ -130,7 +127,7 @@ public async Task Should_Get_Private_Chat() public async Task Should_Get_Chat_Members_Count() { int membersCount = await BotClient.GetChatMemberCountAsync( - chatId: _fixture.SupergroupChat.Id + chatId: fixture.SupergroupChat.Id ); Assert.True(2 <= membersCount); // at least, Bot and the Creator @@ -145,7 +142,7 @@ public async Task Should_Get_Chat_Members_Count() public async Task Should_Send_Chat_Action() { await BotClient.SendChatActionAsync( - chatId: _fixture.SupergroupChat.Id, + chatId: fixture.SupergroupChat.Id, chatAction: ChatAction.RecordVoice ); diff --git a/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs b/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs index 9eedc99cf..9d7e64190 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -8,20 +9,13 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.Dice)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class DiceTests +public class DiceTests(TestsFixture testsFixture) { - readonly TestsFixture _testsFixture; - - public DiceTests(TestsFixture testsFixture) - { - _testsFixture = testsFixture; - } - [OrderedFact("Should send a die")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Die() { - Message message = await _testsFixture.BotClient.SendDiceAsync(_testsFixture.SupergroupChat); + Message message = await testsFixture.BotClient.SendDiceAsync(testsFixture.SupergroupChat); Assert.Equal(MessageType.Dice, message.Type); Assert.NotNull(message.Dice); @@ -33,8 +27,8 @@ public async Task Should_Send_A_Die() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Dart() { - Message message = await _testsFixture.BotClient.SendDiceAsync( - _testsFixture.SupergroupChat, + Message message = await testsFixture.BotClient.SendDiceAsync( + testsFixture.SupergroupChat, emoji: Emoji.Darts ); @@ -48,8 +42,8 @@ public async Task Should_Send_A_Dart() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Basketball() { - Message message = await _testsFixture.BotClient.SendDiceAsync( - _testsFixture.SupergroupChat, + Message message = await testsFixture.BotClient.SendDiceAsync( + testsFixture.SupergroupChat, emoji: Emoji.Basketball ); @@ -63,9 +57,12 @@ public async Task Should_Send_A_Basketball() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Football() { - Message message = await _testsFixture.BotClient.SendDiceAsync( - _testsFixture.SupergroupChat, - emoji: Emoji.Football + Message message = await testsFixture.BotClient.SendDiceAsync( + new SendDiceRequest + { + ChatId = testsFixture.SupergroupChat, + Emoji = Emoji.Football, + } ); Assert.Equal(MessageType.Dice, message.Type); @@ -77,9 +74,12 @@ public async Task Should_Send_A_Football() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_SlotMachine() { - Message message = await _testsFixture.BotClient.SendDiceAsync( - _testsFixture.SupergroupChat, - emoji: Emoji.SlotMachine + Message message = await testsFixture.BotClient.SendDiceAsync( + new SendDiceRequest + { + ChatId = testsFixture.SupergroupChat, + Emoji = Emoji.SlotMachine, + } ); Assert.Equal(MessageType.Dice, message.Type); @@ -92,9 +92,12 @@ public async Task Should_Send_A_SlotMachine() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Bowling() { - Message message = await _testsFixture.BotClient.SendDiceAsync( - _testsFixture.SupergroupChat, - emoji: Emoji.Bowling + Message message = await testsFixture.BotClient.SendDiceAsync( + new SendDiceRequest() + { + ChatId = testsFixture.SupergroupChat, + Emoji = Emoji.Bowling + } ); Assert.Equal(MessageType.Dice, message.Type); @@ -102,4 +105,4 @@ public async Task Should_Send_A_Bowling() Assert.Equal("🎳", message.Dice.Emoji); Assert.InRange(message.Dice.Value, 1, 6); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs b/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs index fbe997250..157eb0ebe 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs @@ -13,20 +13,10 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.FileDownload)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class FileDownloadTests : IClassFixture +public class FileDownloadTests(TestsFixture fixture, FileDownloadTests.Fixture classFixture, ITestOutputHelper output) + : IClassFixture { - readonly ITestOutputHelper _output; - readonly Fixture _classFixture; - readonly TestsFixture _fixture; - - ITelegramBotClient BotClient => _fixture.BotClient; - - public FileDownloadTests(TestsFixture fixture, Fixture classFixture, ITestOutputHelper output) - { - _fixture = fixture; - _classFixture = classFixture; - _output = output; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should get file info")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetFile)] @@ -40,8 +30,8 @@ public async Task Should_Get_File_Info() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Documents.Hamlet)) { documentMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileStream(stream) + chatId: fixture.SupergroupChat, + document: InputFile.FromStream(stream) ); } @@ -57,20 +47,20 @@ public async Task Should_Get_File_Info() Assert.NotNull(file.FilePath); Assert.NotEmpty(file.FilePath); - _classFixture.File = file; + classFixture.File = file; } [OrderedFact("Should download file using file_path and write it to disk")] public async Task Should_Download_Write_Using_FilePath() { - long? fileSize = _classFixture.File.FileSize; + long? fileSize = classFixture.File.FileSize; string destinationFilePath = $"{Path.GetTempFileName()}.{Fixture.FileType}"; - _output.WriteLine($@"Writing file to ""{destinationFilePath}"""); + output.WriteLine($@"Writing file to ""{destinationFilePath}"""); await using FileStream fileStream = System.IO.File.OpenWrite(destinationFilePath); await BotClient.DownloadFileAsync( - filePath: _classFixture.File.FilePath!, + filePath: classFixture.File.FilePath!, destination: fileStream ); @@ -81,21 +71,21 @@ await BotClient.DownloadFileAsync( [OrderedFact("Should download file using file_id and write it to disk")] public async Task Should_Download_Write_Using_FileId() { - long? fileSize = _classFixture.File.FileSize; + long? fileSize = classFixture.File.FileSize; string destinationFilePath = $"{Path.GetTempFileName()}.{Fixture.FileType}"; - _output.WriteLine($@"Writing file to ""{destinationFilePath}"""); + output.WriteLine($@"Writing file to ""{destinationFilePath}"""); await using FileStream fileStream = System.IO.File.OpenWrite(destinationFilePath); File file = await BotClient.GetInfoAndDownloadFileAsync( - fileId: _classFixture.File.FileId, + fileId: classFixture.File.FileId, destination: fileStream ); Assert.NotNull(fileSize); Assert.InRange(fileStream.Length, (int)fileSize - 100, (int)fileSize + 100); Assert.True(JToken.DeepEquals( - JToken.FromObject(_classFixture.File), JToken.FromObject(file) + JToken.FromObject(classFixture.File), JToken.FromObject(file) )); } diff --git a/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs b/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs index b8deec958..26f9f0daf 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs @@ -8,23 +8,16 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.GetUserProfilePhotos)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class GetUserProfileTests +public class GetUserProfileTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public GetUserProfileTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should get bot’s profile photos")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetUserProfilePhotos)] public async Task Should_Get_User_Profile_Photos() { UserProfilePhotos profilePhotos = await BotClient.GetUserProfilePhotosAsync( - userId: _fixture.BotUser.Id + userId: fixture.BotUser.Id ); Assert.True(1 <= profilePhotos.TotalCount); diff --git a/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs b/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs index 47c89ece3..743112c87 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs @@ -6,16 +6,9 @@ namespace Telegram.Bot.Tests.Integ.Other; [Collection(Constants.TestCollections.LeaveChat)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class LeaveChatTests +public class LeaveChatTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public LeaveChatTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should leave chat", Skip = "Bot should stay in chat for other the test cases")] @@ -24,7 +17,7 @@ public async Task Should_Get_Private_Chat() { // ToDo: Exception when leaving private chat await BotClient.LeaveChatAsync( - chatId: _fixture.SupergroupChat + chatId: fixture.SupergroupChat ); } } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/Payments/PaymentFixture.cs b/test/Telegram.Bot.Tests.Integ/Payments/PaymentFixture.cs index dc645ca90..184441507 100644 --- a/test/Telegram.Bot.Tests.Integ/Payments/PaymentFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Payments/PaymentFixture.cs @@ -12,14 +12,7 @@ public PaymentFixture(TestsFixture testsFixture) : base(testsFixture, Constants.TestCollections.Payment) { PaymentProviderToken = testsFixture.Configuration.PaymentProviderToken; - if (PaymentProviderToken is null) - { - throw new ArgumentNullException(nameof(PaymentProviderToken)); - } - - if (PaymentProviderToken.Length < 5) - { - throw new ArgumentException("Payment provider token is invalid", nameof(PaymentProviderToken)); - } + ArgumentNullException.ThrowIfNull(PaymentProviderToken); + ArgumentOutOfRangeException.ThrowIfLessThan(PaymentProviderToken.Length, 5); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Payments/PaymentTests.cs b/test/Telegram.Bot.Tests.Integ/Payments/PaymentTests.cs index 7c4d4e26f..dc74b5d75 100644 --- a/test/Telegram.Bot.Tests.Integ/Payments/PaymentTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Payments/PaymentTests.cs @@ -18,25 +18,17 @@ namespace Telegram.Bot.Tests.Integ.Payments; [Collection(Constants.TestCollections.Payment)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class PaymentTests : IClassFixture, IAsyncLifetime +public class PaymentTests(TestsFixture fixture, PaymentFixture classFixture) + : IClassFixture, IAsyncLifetime { - readonly TestsFixture _fixture; - readonly PaymentFixture _classFixture; - - ITelegramBotClient BotClient => _fixture.BotClient; - - public PaymentTests(TestsFixture fixture, PaymentFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send an invoice")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendInvoice)] public async Task Should_Send_Invoice() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Lunar crater \"Copernicus\"") .WithDescription(description: "It was named after the astronomer Nicolaus Copernicus. It may have been created by debris" + @@ -51,8 +43,8 @@ public async Task Should_Send_Invoice() .WithCurrency(currency: "USD") .WithStartParameter(startParameter: "crater-copernicus") .WithPayload(payload: "") - .WithPaymentProviderToken(paymentsProviderToken: _classFixture.PaymentProviderToken) - .ToChat(chatId: _classFixture.PrivateChat.Id); + .WithPaymentProviderToken(paymentsProviderToken: classFixture.PaymentProviderToken) + .ToChat(chatId: classFixture.PrivateChat.Id); PreliminaryInvoice preliminaryInvoice = paymentsBuilder.GetPreliminaryInvoice(); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -75,7 +67,7 @@ public async Task Should_Send_Invoice() public async Task Should_Answer_Shipping_Query_With_Ok() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -87,7 +79,7 @@ public async Task Should_Answer_Shipping_Query_With_Ok() width: 1280, height: 820 )) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) @@ -96,15 +88,15 @@ public async Task Should_Answer_Shipping_Query_With_Ok() .WithPayload("") .WithFlexible() .RequireShippingAddress() - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() .CurrencyFormat(); string instruction = FormatInstructionWithCurrency($"Click on *Pay {totalCostWithoutShippingCost:C}* and send your shipping address."); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -133,7 +125,7 @@ public async Task Should_Answer_Shipping_Query_With_Ok() public async Task Should_Answer_PreCheckout_Query_With_Ok_And_Shipment_Option() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -145,7 +137,7 @@ public async Task Should_Answer_PreCheckout_Query_With_Ok_And_Shipment_Option() width: 1280, height: 820 )) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) @@ -154,8 +146,8 @@ public async Task Should_Answer_PreCheckout_Query_With_Ok_And_Shipment_Option() .WithPayload("") .WithFlexible() .RequireShippingAddress() - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -164,7 +156,7 @@ public async Task Should_Answer_PreCheckout_Query_With_Ok_And_Shipment_Option() string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}* and send your shipping address. Then click *Pay {totalCostWithoutShippingCost:C}* inside payment dialog. Transaction should be completed." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -181,8 +173,8 @@ public async Task Should_Answer_PreCheckout_Query_With_Ok_And_Shipment_Option() Update preCheckoutUpdate = await GetPreCheckoutQueryUpdate(); PreCheckoutQuery query = preCheckoutUpdate.PreCheckoutQuery; - await _fixture.BotClient.AnswerPreCheckoutQueryAsync( - preCheckoutQueryId: query!.Id + await fixture.BotClient.AnswerPreCheckoutQueryAsync( + new AnswerPreCheckoutQueryRequest(query!.Id) ); PreliminaryInvoice preliminaryInvoice = paymentsBuilder.GetPreliminaryInvoice(); @@ -193,7 +185,7 @@ await _fixture.BotClient.AnswerPreCheckoutQueryAsync( Assert.Equal("", query.InvoicePayload); Assert.Equal(totalAmount, query.TotalAmount); Assert.Equal(preliminaryInvoice.Currency, query.Currency); - Assert.Contains(query.From.Username, _fixture.UpdateReceiver.AllowedUsernames); + Assert.Contains(query.From.Username, fixture.UpdateReceiver.AllowedUsernames); Assert.NotNull(query.OrderInfo); Assert.Null(query.OrderInfo.PhoneNumber); Assert.Null(query.OrderInfo.Name); @@ -207,7 +199,7 @@ await _fixture.BotClient.AnswerPreCheckoutQueryAsync( public async Task Should_Receive_Successful_Payment_With_Shipment_Option() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -219,7 +211,7 @@ public async Task Should_Receive_Successful_Payment_With_Shipment_Option() width: 1280, height: 820 )) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) @@ -233,8 +225,8 @@ public async Task Should_Receive_Successful_Payment_With_Shipment_Option() .RequireShippingAddress() .SendEmailToProvider() .SendPhoneNumberToProvider() - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -243,7 +235,7 @@ public async Task Should_Receive_Successful_Payment_With_Shipment_Option() string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}*, send your shipping address and confirm payment. Transaction should be completed." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -260,8 +252,8 @@ public async Task Should_Receive_Successful_Payment_With_Shipment_Option() Update preCheckoutUpdate = await GetPreCheckoutQueryUpdate(); PreCheckoutQuery query = preCheckoutUpdate.PreCheckoutQuery; - await _fixture.BotClient.AnswerPreCheckoutQueryAsync( - preCheckoutQueryId: query!.Id + await fixture.BotClient.AnswerPreCheckoutQueryAsync( + new AnswerPreCheckoutQueryRequest(query!.Id) ); Update successfulPaymentUpdate = await GetSuccessfulPaymentUpdate(); @@ -291,7 +283,7 @@ await _fixture.BotClient.AnswerPreCheckoutQueryAsync( public async Task Should_Receive_Successful_Payment_With_A_Tip() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Three tasty donuts") .WithDescription(description: "Donuts with special glaze") .WithProductPrice(label: "Donut with chocolate glaze", amount: 550) @@ -306,8 +298,8 @@ public async Task Should_Receive_Successful_Payment_With_A_Tip() .WithPayload("") .WithSuggestedTips(100, 150, 200) .WithMaxTip(maxTipAmount: 300) - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -316,15 +308,15 @@ public async Task Should_Receive_Successful_Payment_With_A_Tip() string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}*, select a tip from given options and confirm payment. Transaction should be completed." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); Message invoiceMessage = await BotClient.MakeRequestAsync(requestRequest); Update preCheckoutUpdate = await GetPreCheckoutQueryUpdate(); PreCheckoutQuery query = preCheckoutUpdate.PreCheckoutQuery; - await _fixture.BotClient.AnswerPreCheckoutQueryAsync( - preCheckoutQueryId: query!.Id + await fixture.BotClient.AnswerPreCheckoutQueryAsync( + new AnswerPreCheckoutQueryRequest(query!.Id) ); Update successfulPaymentUpdate = await GetSuccessfulPaymentUpdate(); @@ -346,7 +338,7 @@ await _fixture.BotClient.AnswerPreCheckoutQueryAsync( public async Task Should_Answer_Shipping_Query_With_Error() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -358,7 +350,7 @@ public async Task Should_Answer_Shipping_Query_With_Error() width: 1280, height: 820 )) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) @@ -367,8 +359,8 @@ public async Task Should_Answer_Shipping_Query_With_Error() .WithPayload("") .WithFlexible() .RequireShippingAddress() - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -377,7 +369,7 @@ public async Task Should_Answer_Shipping_Query_With_Error() string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}* and send your shipping address. You will receive an error. Close payment window after that." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -399,7 +391,7 @@ public async Task Should_Answer_Shipping_Query_With_Error() public async Task Should_Answer_PreCheckout_Query_With_Error_For_No_Shipment_Option() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -413,8 +405,8 @@ public async Task Should_Answer_PreCheckout_Query_With_Error_For_No_Shipment_Opt )) .WithCurrency("USD") .WithPayload("") - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -423,7 +415,7 @@ public async Task Should_Answer_PreCheckout_Query_With_Error_For_No_Shipment_Opt string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}* and confirm payment. You should receive an error. Close payment window after that." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -432,9 +424,13 @@ public async Task Should_Answer_PreCheckout_Query_With_Error_For_No_Shipment_Opt Update preCheckoutUpdate = await GetPreCheckoutQueryUpdate(); PreCheckoutQuery query = preCheckoutUpdate.PreCheckoutQuery; - await _fixture.BotClient.AnswerPreCheckoutQueryAsync( - preCheckoutQueryId: query!.Id, - errorMessage: "Sorry, we couldn't process the transaction. Please, contact our support." + await fixture.BotClient.AnswerPreCheckoutQueryAsync( + new AnswerPreCheckoutQueryRequest() + { + PreCheckoutQueryId = query!.Id, + ErrorMessage = "Sorry, we couldn't process the transaction. Please, contact our support.", + Ok = false, + } ); } @@ -443,7 +439,7 @@ await _fixture.BotClient.AnswerPreCheckoutQueryAsync( public async Task Should_Throw_When_Send_Invoice_Invalid_Provider_Data() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -458,8 +454,8 @@ public async Task Should_Throw_When_Send_Invoice_Invalid_Provider_Data() .WithCurrency("USD") .WithPayload("") .WithProviderData("INVALID-JSON") - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -476,7 +472,7 @@ public async Task Should_Throw_When_Send_Invoice_Invalid_Provider_Data() public async Task Should_Throw_When_Answer_Shipping_Query_With_Duplicate_Shipping_Id() { PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -488,12 +484,12 @@ public async Task Should_Throw_When_Answer_Shipping_Query_With_Duplicate_Shippin width: 1280, height: 820 )) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) .WithPrice(label: "Shipping price", amount: 337_600)) - .WithShipping(_ => _ + .WithShipping(s => s .WithTitle(title: "DHL Express (Duplicate)") .WithId(id: "dhl-express") .WithPrice(label: "Packaging", amount: 400_000) @@ -502,8 +498,8 @@ public async Task Should_Throw_When_Answer_Shipping_Query_With_Duplicate_Shippin .WithPayload("") .WithFlexible() .RequireShippingAddress() - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); double totalCostWithoutShippingCost = paymentsBuilder .GetTotalAmountWithoutShippingCost() @@ -512,7 +508,7 @@ public async Task Should_Throw_When_Answer_Shipping_Query_With_Duplicate_Shippin string instruction = FormatInstructionWithCurrency( $"Click on *Pay {totalCostWithoutShippingCost:C}*, send your shipping address. You should receive an error." ); - await _fixture.SendTestInstructionsAsync(instruction, chatId: _classFixture.PrivateChat.Id); + await fixture.SendTestInstructionsAsync(instruction, chatId: classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -531,9 +527,13 @@ public async Task Should_Throw_When_Answer_Shipping_Query_With_Duplicate_Shippin Assert.Equal(400, exception.ErrorCode); Assert.Equal("Bad Request: SHIPPING_ID_DUPLICATE", exception.Message); - await _fixture.BotClient.AnswerShippingQueryAsync( - shippingQueryId: shippingUpdate.ShippingQuery.Id, - errorMessage: "✅ Test Passed" + await fixture.BotClient.AnswerShippingQueryAsync( + new() + { + Ok = false, + ShippingQueryId = shippingUpdate.ShippingQuery.Id, + ErrorMessage = "✅ Test Passed", + } ); } @@ -541,21 +541,17 @@ await _fixture.BotClient.AnswerShippingQueryAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendInvoice)] public async Task Should_Send_Invoice_With_Reply_Markup() { - InlineKeyboardMarkup replyMarkup = new(new[] - { - new[] - { + InlineKeyboardMarkup replyMarkup = new( + [ + [ InlineKeyboardButton.WithPayment("Pay this invoice"), InlineKeyboardButton.WithUrl("Repository", "https://github.com/TelegramBots/Telegram.Bot") - }, - new[] - { - InlineKeyboardButton.WithCallbackData("Some other button") - } - }); + ], + [InlineKeyboardButton.WithCallbackData("Some other button")] + ]); PaymentsBuilder paymentsBuilder = new PaymentsBuilder() - .WithProduct(_ => _ + .WithProduct(p => p .WithTitle(title: "Reproduction of \"La nascita di Venere\"") .WithDescription(description: "Sandro Botticelli’s the Birth of Venus depicts the goddess Venus arriving at the shore" + @@ -570,8 +566,8 @@ public async Task Should_Send_Invoice_With_Reply_Markup() .WithCurrency("USD") .WithPayload("") .WithReplyMarkup(replyMarkup) - .WithPaymentProviderToken(_classFixture.PaymentProviderToken) - .ToChat(_classFixture.PrivateChat.Id); + .WithPaymentProviderToken(classFixture.PaymentProviderToken) + .ToChat(classFixture.PrivateChat.Id); SendInvoiceRequest requestRequest = paymentsBuilder.BuildInvoiceRequest(); @@ -580,34 +576,35 @@ public async Task Should_Send_Invoice_With_Reply_Markup() async Task GetShippingQueryUpdate(CancellationToken cancellationToken = default) { - Update[] updates = await _fixture.UpdateReceiver.GetUpdatesAsync( + Update[] updates = await fixture.UpdateReceiver.GetUpdatesAsync( cancellationToken: cancellationToken, updateTypes: UpdateType.ShippingQuery ); Update update = updates.Single(); - await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); + await fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); return update; } async Task GetPreCheckoutQueryUpdate(CancellationToken cancellationToken = default) { - Update[] updates = await _fixture.UpdateReceiver.GetUpdatesAsync( + Update[] updates = await fixture.UpdateReceiver.GetUpdatesAsync( cancellationToken: cancellationToken, - updateTypes: UpdateType.PreCheckoutQuery); + updateTypes: UpdateType.PreCheckoutQuery + ); Update update = updates.Single(); - await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); + await fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); return update; } async Task GetSuccessfulPaymentUpdate(CancellationToken cancellationToken = default) { - Update[] updates = await _fixture.UpdateReceiver.GetUpdatesAsync( + Update[] updates = await fixture.UpdateReceiver.GetUpdatesAsync( predicate: u => u.Message?.Type == MessageType.SuccessfulPayment, cancellationToken: cancellationToken, updateTypes: UpdateType.Message @@ -615,12 +612,12 @@ async Task GetSuccessfulPaymentUpdate(CancellationToken cancellationToke Update update = updates.Single(); - await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); + await fixture.UpdateReceiver.DiscardNewUpdatesAsync(cancellationToken); return update; } - public async Task InitializeAsync() => await _fixture.UpdateReceiver.DiscardNewUpdatesAsync(); + public async Task InitializeAsync() => await fixture.UpdateReceiver.DiscardNewUpdatesAsync(); public Task DisposeAsync() => Task.CompletedTask; public static string FormatInstructionWithCurrency(FormattableString instruction) => diff --git a/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs b/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs index d014cc4a0..9dfd5914a 100644 --- a/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs +++ b/test/Telegram.Bot.Tests.Integ/Payments/PaymentsBuilder.cs @@ -32,35 +32,37 @@ public class PaymentsBuilder public PaymentsBuilder WithCurrency(string currency) { - if (string.IsNullOrWhiteSpace(currency)) throw new ArgumentException($"{nameof(currency)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(currency); _currency = currency; return this; } public PaymentsBuilder WithStartParameter(string startParameter) { - if (string.IsNullOrWhiteSpace(startParameter)) throw new ArgumentException($"{nameof(startParameter)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(startParameter); _startParameter = startParameter; return this; } public PaymentsBuilder WithPayload(string payload) { - if (string.IsNullOrWhiteSpace(payload)) throw new ArgumentException($"{nameof(payload)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(payload); _payload = payload; return this; } public PaymentsBuilder WithProviderData(string providerData) { - if (string.IsNullOrWhiteSpace(providerData)) throw new ArgumentException($"{nameof(providerData)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(providerData); + _providerData = providerData; return this; } public PaymentsBuilder WithReplyMarkup(InlineKeyboardMarkup replyMarkup) { - _replyMarkup = replyMarkup ?? throw new ArgumentNullException(nameof(replyMarkup)); + ArgumentNullException.ThrowIfNull(replyMarkup); + _replyMarkup = replyMarkup; return this; } @@ -114,21 +116,15 @@ public PaymentsBuilder SendPhoneNumberToProvider(bool send = true) public PaymentsBuilder WithPaymentProviderToken(string paymentsProviderToken) { - if (string.IsNullOrWhiteSpace(paymentsProviderToken)) throw new ArgumentException($"{nameof(paymentsProviderToken)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(paymentsProviderToken); _paymentsProviderToken = paymentsProviderToken; return this; } public PaymentsBuilder WithMaxTip(int maxTipAmount) { - if (maxTipAmount < 1) - throw new ArgumentOutOfRangeException( - nameof(maxTipAmount), - maxTipAmount, - "Max tip amount must be greater than 0" - ); - - if (_suggestedTipAmounts is not null && _suggestedTipAmounts.Any(_ => _ > maxTipAmount)) + ArgumentOutOfRangeException.ThrowIfLessThan(maxTipAmount, 1); + if (_suggestedTipAmounts is not null && _suggestedTipAmounts.Any(tip => tip > maxTipAmount)) { throw new ArgumentOutOfRangeException( nameof(maxTipAmount), @@ -144,27 +140,16 @@ public PaymentsBuilder WithMaxTip(int maxTipAmount) public PaymentsBuilder WithSuggestedTips(params int[] suggestedTipAmounts) { - if (suggestedTipAmounts.Length is 0) - { - throw new ArgumentException("Suggested tips must not be empty"); - } + ArgumentOutOfRangeException.ThrowIfZero(suggestedTipAmounts.Length); + ArgumentOutOfRangeException.ThrowIfGreaterThan(suggestedTipAmounts.Length, 4); - if (suggestedTipAmounts.Length > 4) - { - throw new ArgumentException("No more than four suggested tips can be set"); - } - - if (suggestedTipAmounts.Any(_ => _ < 1)) - { + if (suggestedTipAmounts.Any(tip => tip < 1)) throw new ArgumentException("Suggested tips must be greater than 0"); - } - if (_maxTipAmount is not null && suggestedTipAmounts.Any(_ => _ < _maxTipAmount)) - { + if (_maxTipAmount is not null && suggestedTipAmounts.Any(tip => tip < _maxTipAmount)) throw new ArgumentException("Suggested tips must not be greater than max tip amount"); - } - _suggestedTipAmounts = suggestedTipAmounts.OrderBy(_ => _).ToArray(); + _suggestedTipAmounts = suggestedTipAmounts.OrderBy(tip => tip).ToArray(); return this; } @@ -194,11 +179,11 @@ public int GetTotalAmount() => public SendInvoiceRequest BuildInvoiceRequest() { - if (_product is null) throw new InvalidOperationException("Product wasn't added"); - if (string.IsNullOrWhiteSpace(_paymentsProviderToken)) throw new ArgumentException("Payments provider token is null or empty"); - if (_chatId is null) throw new InvalidOperationException("ChatId is null"); - if (string.IsNullOrWhiteSpace(_currency)) throw new InvalidOperationException("Currency isn't set"); - if (string.IsNullOrWhiteSpace(_payload)) throw new InvalidOperationException("Payload isn't set"); + ArgumentNullException.ThrowIfNull(_product); + ArgumentException.ThrowIfNullOrWhiteSpace(_paymentsProviderToken); + ArgumentNullException.ThrowIfNull(_chatId); + ArgumentException.ThrowIfNullOrWhiteSpace(_currency); + ArgumentException.ThrowIfNullOrWhiteSpace(_payload); return new() { @@ -229,7 +214,7 @@ public SendInvoiceRequest BuildInvoiceRequest() public AnswerShippingQueryRequest BuildShippingQueryRequest(string shippingQueryId, string? errorMessage = default) { - if (string.IsNullOrWhiteSpace(shippingQueryId)) throw new ArgumentNullException(nameof(shippingQueryId)); + ArgumentException.ThrowIfNullOrWhiteSpace(shippingQueryId); AnswerShippingQueryRequest shippingQueryRequest = errorMessage is null ? new(shippingQueryId, _shippingOptions) @@ -266,22 +251,22 @@ public class ShippingOptionsBuilder public ShippingOptionsBuilder WithId(string id) { - if (string.IsNullOrWhiteSpace(id)) throw new ArgumentNullException(nameof(id)); + ArgumentException.ThrowIfNullOrWhiteSpace(id); _id = id; return this; } public ShippingOptionsBuilder WithTitle(string title) { - if (string.IsNullOrWhiteSpace(title)) throw new ArgumentNullException(nameof(title)); + ArgumentException.ThrowIfNullOrWhiteSpace(title); _title = title; return this; } public ShippingOptionsBuilder WithPrice(string label, int amount) { - if (string.IsNullOrWhiteSpace(label)) throw new ArgumentNullException(nameof(label)); - if (amount <= 0) throw new ArgumentOutOfRangeException(nameof(amount), "Price must be greater than 0"); + ArgumentException.ThrowIfNullOrWhiteSpace(label); + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount); _shippingPrices.Add(new(label, amount)); @@ -310,22 +295,23 @@ public class ProductBuilder public ProductBuilder WithTitle(string title) { - if (string.IsNullOrWhiteSpace(title)) throw new ArgumentException($"{nameof(title)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(title); _title = title; return this; } public ProductBuilder WithDescription(string description) { - if (string.IsNullOrWhiteSpace(description)) throw new ArgumentException($"{nameof(description)} is null or empty"); + ArgumentException.ThrowIfNullOrWhiteSpace(description); _description = description; return this; } public ProductBuilder WithPhoto(string url, int width, int height) { - if (string.IsNullOrWhiteSpace(url)) throw new ArgumentException($"{nameof(url)} is null or empty"); - if (width < 1 || height < 1) throw new ArgumentException("Dimensions are invalid"); + ArgumentException.ThrowIfNullOrWhiteSpace(url); + ArgumentOutOfRangeException.ThrowIfLessThan(width, 1); + ArgumentOutOfRangeException.ThrowIfLessThan(height, 1); _photoUrl = url; _photoWidth = width; @@ -336,8 +322,8 @@ public ProductBuilder WithPhoto(string url, int width, int height) public ProductBuilder WithProductPrice(string label, int amount) { - if (string.IsNullOrWhiteSpace(label)) throw new ArgumentNullException(nameof(label)); - if (amount <= 0) throw new ArgumentOutOfRangeException(nameof(amount), "Price must be greater than 0"); + ArgumentException.ThrowIfNullOrWhiteSpace(label); + ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount); _productPrices.Add(new(label, amount)); return this; } diff --git a/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTests.cs b/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTests.cs index caceb8974..f001ca770 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTests.cs @@ -11,17 +11,11 @@ namespace Telegram.Bot.Tests.Integ.Polls; [Collection(Constants.TestCollections.NativePolls)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class AnonymousPollTests : IClassFixture +public class AnonymousPollTests(AnonymousPollTestsFixture classFixture) : IClassFixture { - readonly AnonymousPollTestsFixture _classFixture; - TestsFixture Fixture => _classFixture.TestsFixture; + TestsFixture Fixture => classFixture.TestsFixture; ITelegramBotClient BotClient => Fixture.BotClient; - public AnonymousPollTests( AnonymousPollTestsFixture classFixture) - { - _classFixture = classFixture; - } - [OrderedFact( "Should send a poll", Skip = "Fails on CI server for some reason, the resulting poll is public")] @@ -29,9 +23,12 @@ public AnonymousPollTests( AnonymousPollTestsFixture classFixture) public async Task Should_Send_Poll() { Message message = await BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "Who shot first?", - options: new[] {"Han Solo", "Greedo", "I don't care"} + new() + { + ChatId = Fixture.SupergroupChat, + Question = "Who shot first?", + Options = ["Han Solo", "Greedo", "I don't care"], + } ); Assert.Equal(MessageType.Poll, message.Type); @@ -52,7 +49,7 @@ public async Task Should_Send_Poll() Assert.Equal("I don't care", message.Poll.Options[2].Text); Assert.All(message.Poll.Options, option => Assert.Equal(0, option.VoterCount)); - _classFixture.PollMessage = message; + classFixture.PollMessage = message; } [OrderedFact( @@ -60,7 +57,7 @@ public async Task Should_Send_Poll() Skip = "Fails on CI server for some reason, the resulting poll is public")] public async Task Should_Receive_Poll_State_Update() { - string pollId = _classFixture.PollMessage.Poll!.Id; + string pollId = classFixture.PollMessage.Poll!.Id; await Fixture.SendTestInstructionsAsync("🗳 Vote for any of the options on the poll above 👆"); Update update = (await Fixture.UpdateReceiver.GetUpdatesAsync(updateTypes: UpdateType.Poll)) @@ -78,11 +75,14 @@ public async Task Should_Receive_Poll_State_Update() public async Task Should_Stop_Poll() { Poll poll = await BotClient.StopPollAsync( - chatId: _classFixture.PollMessage.Chat, - messageId: _classFixture.PollMessage.MessageId + new() + { + ChatId = classFixture.PollMessage.Chat, + MessageId = classFixture.PollMessage.MessageId, + } ); - Assert.Equal(_classFixture.PollMessage.Poll!.Id, poll.Id); + Assert.Equal(classFixture.PollMessage.Poll!.Id, poll.Id); Assert.True(poll.IsClosed); } @@ -92,13 +92,16 @@ public async Task Should_Throw_Exception_Not_Enough_Options() { ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "You should never see this poll", - options: new[] {"The only poll option"} + new() + { + ChatId = Fixture.SupergroupChat, + Question = "You should never see this poll", + Options = ["The only poll option"], + } ) ); Assert.IsType(exception); Assert.Equal("Bad Request: poll must have at least 2 option", exception.Message); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTestsFixture.cs index c398e289c..82fef8c9a 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/AnonymousPollTestsFixture.cs @@ -3,14 +3,9 @@ namespace Telegram.Bot.Tests.Integ.Polls; -public class AnonymousPollTestsFixture +public class AnonymousPollTestsFixture(TestsFixture testsFixture) { - public TestsFixture TestsFixture { get; } + public TestsFixture TestsFixture { get; } = testsFixture; public Message PollMessage { get; set; } - - public AnonymousPollTestsFixture(TestsFixture testsFixture) - { - TestsFixture = testsFixture; - } } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTests.cs b/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTests.cs index 4116a01d1..43b9b8050 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTests.cs @@ -10,17 +10,11 @@ namespace Telegram.Bot.Tests.Integ.Polls; [Collection(Constants.TestCollections.NativePolls)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class PublicPollTests : IClassFixture +public class PublicPollTests(PublicPollTestsFixture classFixture) : IClassFixture { - readonly PublicPollTestsFixture _classFixture; - TestsFixture Fixture => _classFixture.TestsFixture; + TestsFixture Fixture => classFixture.TestsFixture; ITelegramBotClient BotClient => Fixture.BotClient; - public PublicPollTests(PublicPollTestsFixture classFixture) - { - _classFixture = classFixture; - } - [OrderedFact( "Should send public poll with multiple answers", Skip = "Poll tests fail too often for unknown reasons")] @@ -28,12 +22,15 @@ public PublicPollTests(PublicPollTestsFixture classFixture) public async Task Should_Send_Non_Anonymous_Poll_With_Multiple_Answers() { Message message = await Fixture.BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "Pick your team", - options: new [] { "Aragorn", "Galadriel", "Frodo" }, - isAnonymous: false, - type: PollType.Regular, - allowsMultipleAnswers: true + new() + { + ChatId = Fixture.SupergroupChat, + Question = "Pick your team", + Options = ["Aragorn", "Galadriel", "Frodo"], + IsAnonymous = false, + Type = PollType.Regular, + AllowsMultipleAnswers = true, + } ); Assert.Equal(MessageType.Poll, message.Type); @@ -54,7 +51,7 @@ public async Task Should_Send_Non_Anonymous_Poll_With_Multiple_Answers() Assert.Equal("Frodo", message.Poll.Options[2].Text); Assert.All(message.Poll.Options, option => Assert.Equal(0, option.VoterCount)); - _classFixture.OriginalPollMessage = message; + classFixture.OriginalPollMessage = message; } [OrderedFact( @@ -71,7 +68,7 @@ await Fixture.SendTestInstructionsAsync( updateTypes: UpdateType.PollAnswer ); - Poll poll = _classFixture.OriginalPollMessage.Poll; + Poll poll = classFixture.OriginalPollMessage.Poll; PollAnswer pollAnswer = pollAnswerUpdate.PollAnswer; Assert.NotNull(pollAnswer); @@ -82,7 +79,7 @@ await Fixture.SendTestInstructionsAsync( optionId => Assert.True(optionId < poll.Options.Length) ); - _classFixture.PollAnswer = pollAnswer; + classFixture.PollAnswer = pollAnswer; } [OrderedFact( @@ -96,18 +93,21 @@ public async Task Should_Stop_Non_Anonymous_Poll() await Task.Delay(TimeSpan.FromSeconds(5)); Poll closedPoll = await BotClient.StopPollAsync( - chatId: _classFixture.OriginalPollMessage.Chat, - messageId: _classFixture.OriginalPollMessage.MessageId + new() + { + ChatId = classFixture.OriginalPollMessage.Chat, + MessageId = classFixture.OriginalPollMessage.MessageId, + } ); - Assert.Equal(_classFixture.OriginalPollMessage.Poll!.Id, closedPoll.Id); + Assert.Equal(classFixture.OriginalPollMessage.Poll!.Id, closedPoll.Id); Assert.True(closedPoll.IsClosed); - PollAnswer pollAnswer = _classFixture.PollAnswer; + PollAnswer pollAnswer = classFixture.PollAnswer; Assert.All( pollAnswer.OptionIds, optionId => Assert.True(closedPoll.Options[optionId].VoterCount > 0) ); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTestsFixture.cs index 83380b9c7..becab4bad 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/PublicPollTestsFixture.cs @@ -3,14 +3,9 @@ namespace Telegram.Bot.Tests.Integ.Polls; -public class PublicPollTestsFixture +public class PublicPollTestsFixture(TestsFixture testsFixture) { - public TestsFixture TestsFixture { get; } + public TestsFixture TestsFixture { get; } = testsFixture; public Message OriginalPollMessage { get; set; } public PollAnswer PollAnswer { get; set; } - - public PublicPollTestsFixture(TestsFixture testsFixture) - { - TestsFixture = testsFixture; - } } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTests.cs b/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTests.cs index e4b004d4f..3099f8aaf 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTests.cs @@ -10,17 +10,11 @@ namespace Telegram.Bot.Tests.Integ.Polls; [Collection(Constants.TestCollections.NativePolls)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class QuizPollTests : IClassFixture +public class QuizPollTests(QuizPollTestsFixture classFixture) : IClassFixture { - readonly QuizPollTestsFixture _classFixture; - TestsFixture Fixture => _classFixture.TestsFixture; + TestsFixture Fixture => classFixture.TestsFixture; ITelegramBotClient BotClient => Fixture.BotClient; - public QuizPollTests(QuizPollTestsFixture classFixture) - { - _classFixture = classFixture; - } - [OrderedFact( "Should send public quiz poll", Skip = "Poll tests fail too often for unknown reasons")] @@ -28,14 +22,17 @@ public QuizPollTests(QuizPollTestsFixture classFixture) public async Task Should_Send_Public_Quiz_Poll() { Message message = await Fixture.BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "How many silmarils were made in J. R. R. Tolkiens's Silmarillion?", - options: new [] { "One", "Ten", "Three" }, - isAnonymous: false, - type: PollType.Quiz, - correctOptionId: 2, // "Three", - explanation: "Three [silmarils](https://en.wikipedia.org/wiki/Silmarils) were made", - explanationParseMode: ParseMode.MarkdownV2 + new() + { + ChatId = Fixture.SupergroupChat, + Question = "How many silmarils were made in J. R. R. Tolkiens's Silmarillion?", + Options = ["One", "Ten", "Three"], + IsAnonymous = false, + Type = PollType.Quiz, + CorrectOptionId = 2, // "Three", + Explanation = "Three [silmarils](https://en.wikipedia.org/wiki/Silmarils) were made", + ExplanationParseMode = ParseMode.MarkdownV2, + } ); Assert.Equal(MessageType.Poll, message.Type); @@ -64,7 +61,7 @@ public async Task Should_Send_Public_Quiz_Poll() entity.Url == "https://en.wikipedia.org/wiki/Silmarils" ); - _classFixture.OriginalPollMessage = message; + classFixture.OriginalPollMessage = message; } [OrderedFact( @@ -76,7 +73,7 @@ await Fixture.SendTestInstructionsAsync( "🗳 Choose any answer in the quiz above 👆" ); - Poll poll = _classFixture.OriginalPollMessage.Poll; + Poll poll = classFixture.OriginalPollMessage.Poll; Update pollAnswerUpdates = await Fixture.UpdateReceiver.GetUpdateAsync( update => update.PollAnswer?.OptionIds.Length == 1 && @@ -94,7 +91,7 @@ await Fixture.SendTestInstructionsAsync( optionId => Assert.True(optionId < poll.Options.Length) ); - _classFixture.PollAnswer = pollAnswer; + classFixture.PollAnswer = pollAnswer; } [OrderedFact( @@ -108,18 +105,21 @@ public async Task Should_Stop_Quiz_Poll() await Task.Delay(TimeSpan.FromSeconds(5)); Poll closedPoll = await BotClient.StopPollAsync( - chatId: _classFixture.OriginalPollMessage.Chat, - messageId: _classFixture.OriginalPollMessage.MessageId + new() + { + ChatId = classFixture.OriginalPollMessage.Chat, + MessageId = classFixture.OriginalPollMessage.MessageId, + } ); - Assert.Equal(_classFixture.OriginalPollMessage.Poll!.Id, closedPoll.Id); + Assert.Equal(classFixture.OriginalPollMessage.Poll!.Id, closedPoll.Id); Assert.True(closedPoll.IsClosed); - PollAnswer pollAnswer = _classFixture.PollAnswer; + PollAnswer pollAnswer = classFixture.PollAnswer; Assert.All( pollAnswer.OptionIds, optionId => Assert.True(closedPoll.Options[optionId].VoterCount > 0) ); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTestsFixture.cs index fb112e1dc..0d1c32871 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/QuizPollTestsFixture.cs @@ -3,14 +3,9 @@ namespace Telegram.Bot.Tests.Integ.Polls; -public class QuizPollTestsFixture +public class QuizPollTestsFixture(TestsFixture testsFixture) { - public TestsFixture TestsFixture { get; } + public TestsFixture TestsFixture { get; } = testsFixture; public Message OriginalPollMessage { get; set; } public PollAnswer PollAnswer { get; set; } - - public QuizPollTestsFixture(TestsFixture testsFixture) - { - TestsFixture = testsFixture; - } } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTests.cs b/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTests.cs index 2bf070c51..d279b7a95 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTests.cs @@ -9,17 +9,11 @@ namespace Telegram.Bot.Tests.Integ.Polls; [Collection(Constants.TestCollections.NativePolls)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SelfStoppingPollTests : IClassFixture +public class SelfStoppingPollTests(SelfStoppingPollTestsFixture fixture) : IClassFixture { - readonly SelfStoppingPollTestsFixture _classFixture; - TestsFixture Fixture => _classFixture.TestsFixture; + TestsFixture Fixture => fixture.TestsFixture; ITelegramBotClient BotClient => Fixture.BotClient; - public SelfStoppingPollTests(SelfStoppingPollTestsFixture fixture) - { - _classFixture = fixture; - } - [OrderedFact( "Should send self closing anonymous poll by period", Skip = "Fails on CI server for some reason, the resulting poll is public")] @@ -27,10 +21,13 @@ public SelfStoppingPollTests(SelfStoppingPollTestsFixture fixture) public async Task Should_Send_Self_Closing_Poll_Anonymous_Poll_By_Period() { Message message = await BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "Who shot first?", - options: new[] {"Han Solo", "Greedo", "I don't care"}, - openPeriod: 6 + new() + { + ChatId = Fixture.SupergroupChat, + Question = "Who shot first?", + Options = ["Han Solo", "Greedo", "I don't care"], + OpenPeriod = 6, + } ); Assert.Equal(MessageType.Poll, message.Type); @@ -51,8 +48,8 @@ public async Task Should_Send_Self_Closing_Poll_Anonymous_Poll_By_Period() Assert.Equal("I don't care", message.Poll.Options[2].Text); Assert.All(message.Poll.Options, option => Assert.Equal(0, option.VoterCount)); - _classFixture.PollMessage = message; - _classFixture.OpenPeriod = 6; + fixture.PollMessage = message; + fixture.OpenPeriod = 6; } // For some reason Telegram doesn't send poll update when a poll closes itself @@ -83,10 +80,13 @@ public async Task Should_Send_Self_Closing_Poll_Anonymous_Poll_By_Date() DateTime closeDate = DateTime.UtcNow.AddSeconds(8); Message message = await BotClient.SendPollAsync( - chatId: Fixture.SupergroupChat, - question: "Who shot first?", - options: new[] {"Han Solo", "Greedo", "I don't care"}, - closeDate: closeDate + new() + { + ChatId = Fixture.SupergroupChat, + Question = "Who shot first?", + Options = ["Han Solo", "Greedo", "I don't care"], + CloseDate = closeDate, + } ); Assert.Equal(MessageType.Poll, message.Type); @@ -115,8 +115,8 @@ public async Task Should_Send_Self_Closing_Poll_Anonymous_Poll_By_Date() Assert.Equal("I don't care", message.Poll.Options[2].Text); Assert.All(message.Poll.Options, option => Assert.Equal(0, option.VoterCount)); - _classFixture.PollMessage = message; - _classFixture.CloseDate = closeDate; + fixture.PollMessage = message; + fixture.CloseDate = closeDate; } // For some reason Telegram doesn't send poll update when a poll closes itself @@ -142,4 +142,4 @@ public async Task Should_Send_Self_Closing_Poll_Anonymous_Poll_By_Date() // ); // Assert.True(update.Poll.IsClosed); // } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTestsFixture.cs index 1f5a8c4d5..056461b1e 100644 --- a/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Polls/SelfStoppingPollTestsFixture.cs @@ -4,15 +4,10 @@ namespace Telegram.Bot.Tests.Integ.Polls; -public class SelfStoppingPollTestsFixture +public class SelfStoppingPollTestsFixture(TestsFixture testsFixture) { - public TestsFixture TestsFixture { get; } + public TestsFixture TestsFixture { get; } = testsFixture; public Message PollMessage { get; set; } public int OpenPeriod { get; set; } public DateTime CloseDate { get; set; } - - public SelfStoppingPollTestsFixture(TestsFixture testsFixture) - { - TestsFixture = testsFixture; - } } \ No newline at end of file diff --git a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs index fe1e83b4d..79db71931 100644 --- a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs +++ b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/PrivateChatReplyMarkupTests.cs @@ -13,10 +13,7 @@ namespace Telegram.Bot.Tests.Integ.ReplyMarkup; [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] public class PrivateChatReplyMarkupTests(TestsFixture testsFixture, PrivateChatReplyMarkupTests.Fixture fixture) : IClassFixture { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly Fixture _classFixture = fixture; - readonly TestsFixture _fixture = testsFixture; + ITelegramBotClient BotClient => testsFixture.BotClient; [OrderedFact("Should request contact with keyboard reply markup")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] @@ -30,10 +27,13 @@ public async Task Should_Request_Contact() OneTimeKeyboard = true, }; - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Share your contact info using the keyboard reply markup provided.", - replyMarkup: replyKeyboardMarkup + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Share your contact info using the keyboard reply markup provided.", + ReplyMarkup = replyKeyboardMarkup, + } ); Message contactMessage = await GetMessageFromChat(MessageType.Contact); @@ -41,12 +41,15 @@ await BotClient.SendTextMessageAsync( Assert.NotNull(contactMessage.Contact); Assert.NotEmpty(contactMessage.Contact.FirstName); Assert.NotEmpty(contactMessage.Contact.PhoneNumber); - Assert.Equal(_classFixture.PrivateChat.Id, contactMessage.Contact.UserId); - - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Got it. Removing reply keyboard markup...", - replyMarkup: new ReplyKeyboardRemove() + Assert.Equal(fixture.PrivateChat.Id, contactMessage.Contact.UserId); + + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Got it. Removing reply keyboard markup...", + ReplyMarkup = new ReplyKeyboardRemove(), + } ); } @@ -57,20 +60,26 @@ public async Task Should_Request_Location() KeyboardButton[] keyboard = [KeyboardButton.WithRequestLocation("Share Location")]; ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Share your location using the keyboard reply markup", - replyMarkup: replyKeyboardMarkup + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Share your location using the keyboard reply markup", + ReplyMarkup = replyKeyboardMarkup, + } ); Message locationMessage = await GetMessageFromChat(MessageType.Location); Assert.NotNull(locationMessage.Location); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Got it. Removing reply keyboard markup...", - replyMarkup: new ReplyKeyboardRemove() + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Got it. Removing reply keyboard markup...", + ReplyMarkup = new ReplyKeyboardRemove(), + } ); } @@ -84,20 +93,26 @@ public async Task Should_Request_Users() ]; ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Share users using the keyboard reply markup", - replyMarkup: replyKeyboardMarkup + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Share users using the keyboard reply markup", + ReplyMarkup = replyKeyboardMarkup, + } ); Message usersMessage = await GetMessageFromChat(MessageType.UsersShared); Assert.NotNull(usersMessage.UsersShared); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Got it. Removing reply keyboard markup...", - replyMarkup: new ReplyKeyboardRemove() + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Got it. Removing reply keyboard markup...", + ReplyMarkup = new ReplyKeyboardRemove(), + } ); } @@ -114,31 +129,35 @@ public async Task Should_Request_Chat() ]; ReplyKeyboardMarkup replyKeyboardMarkup = new(keyboardRow: keyboard); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Share chat using the keyboard reply markup", - replyMarkup: replyKeyboardMarkup + await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.PrivateChat, + Text = "Share chat using the keyboard reply markup", + ReplyMarkup = replyKeyboardMarkup, + } ); Message chatMessage = await GetMessageFromChat(MessageType.ChatShared); Assert.NotNull(chatMessage.ChatShared); - await BotClient.SendTextMessageAsync( - chatId: _classFixture.PrivateChat, - text: "Got it. Removing reply keyboard markup...", - replyMarkup: new ReplyKeyboardRemove() + await BotClient.SendMessageAsync( + new(){ + ChatId = fixture.PrivateChat, + Text = "Got it. Removing reply keyboard markup...", + ReplyMarkup = new ReplyKeyboardRemove(), + } ); } async Task GetMessageFromChat(MessageType messageType) => - (await _fixture.UpdateReceiver.GetUpdateAsync( + (await testsFixture.UpdateReceiver.GetUpdateAsync( predicate: u => u.Message!.Type == messageType && - u.Message.Chat.Id == _classFixture.PrivateChat.Id, + u.Message.Chat.Id == fixture.PrivateChat.Id, updateTypes: UpdateType.Message )).Message; - public class Fixture(TestsFixture testsFixture) : PrivateChatFixture(testsFixture, Constants.TestCollections.ReplyMarkup) - { - } + public class Fixture(TestsFixture testsFixture) + : PrivateChatFixture(testsFixture, Constants.TestCollections.ReplyMarkup); } diff --git a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs index a9dd301e4..ec572c6a4 100644 --- a/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs +++ b/test/Telegram.Bot.Tests.Integ/ReplyMarkup/ReplyMarkupTests.cs @@ -11,18 +11,19 @@ namespace Telegram.Bot.Tests.Integ.ReplyMarkup; [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] public class ReplyMarkupTests(TestsFixture testsFixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture = testsFixture; + ITelegramBotClient BotClient => testsFixture.BotClient; [OrderedFact("Should send a message with force reply markup")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Force_Reply() { - await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat, - text: "Message with force_reply", - replyMarkup: new ForceReplyMarkup() + await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = "Message with force_reply", + ReplyMarkup = new ForceReplyMarkup(), + } ); } @@ -42,10 +43,13 @@ public async Task Should_Send_MultiRow_Keyboard() ResizeKeyboard = true, }; - await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat, - text: "Message with 3x3 keyboard", - replyMarkup: replyMarkup + await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = "Message with 3x3 keyboard", + ReplyMarkup = replyMarkup, + } ); } @@ -53,10 +57,13 @@ await BotClient.SendTextMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Remove_Reply_Keyboard() { - await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat, - text: "Message to remove keyboard", - replyMarkup: new ReplyKeyboardRemove() + await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = "Message to remove keyboard", + ReplyMarkup = new ReplyKeyboardRemove(), + } ); } @@ -81,10 +88,13 @@ public async Task Should_Send_Inline_Keyboard() InlineKeyboardMarkup replyMarkup = new(keyboard); - Message sentMessage = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat, - text: "Message with inline keyboard markup", - replyMarkup: replyMarkup + Message sentMessage = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = "Message with inline keyboard markup", + ReplyMarkup = replyMarkup, + } ); Asserts.JsonEquals(replyMarkup, sentMessage.ReplyMarkup); diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs index c33c0d231..86a75d2a4 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/AlbumMessageTests.cs @@ -1,7 +1,7 @@ -using System; using System.IO; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; @@ -12,19 +12,10 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.AlbumMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class AlbumMessageTests : IClassFixture> +public class AlbumMessageTests(TestsFixture testsFixture, EntitiesFixture classFixture) + : IClassFixture> { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly EntitiesFixture _classFixture; - - readonly TestsFixture _fixture; - - public AlbumMessageTests(TestsFixture testsFixture, EntitiesFixture classFixture) - { - _fixture = testsFixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => testsFixture.BotClient; [OrderedFact("Should upload 2 photos with captions and send them in an album")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMediaGroup)] @@ -36,24 +27,24 @@ public async Task Should_Upload_2_Photos_Album() stream2 = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot) ) { - IAlbumInputMedia[] inputMedia = - [ - new InputMediaPhoto - { - Media = InputFile.FromStream(stream1, "logo.png"), - Caption = "Logo", - }, - new InputMediaPhoto - { - Media = InputFile.FromStream(stream2, "bot.gif"), - Caption = "Bot", - }, - ]; - messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: inputMedia, - disableNotification: true + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaPhoto + { + Media = InputFile.FromStream(stream1, "logo.png"), + Caption = "Logo", + }, + new InputMediaPhoto + { + Media = InputFile.FromStream(stream2, "bot.gif"), + Caption = "Bot", + }, + ], + DisableNotification = true, + } ); } @@ -67,7 +58,7 @@ public async Task Should_Upload_2_Photos_Album() Assert.Equal("Logo", messages[0].Caption); Assert.Equal("Bot", messages[1].Caption); - _classFixture.Entities = messages.ToList(); + classFixture.Entities = messages.ToList(); } [OrderedFact("Should send an album with 3 photos using their file_id")] @@ -75,17 +66,19 @@ public async Task Should_Upload_2_Photos_Album() public async Task Should_Send_3_Photos_Album_Using_FileId() { // Take file_id of photos uploaded in previous test case - string[] fileIds = _classFixture.Entities + string[] fileIds = classFixture.Entities .Select(msg => msg.Photo!.First().FileId) .ToArray(); Message[] messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: new IAlbumInputMedia[] + new() { - new InputMediaPhoto { Media = new InputFileId(fileIds[0])}, - new InputMediaPhoto { Media = new InputFileId(fileIds[1])}, - new InputMediaPhoto { Media = new InputFileId(fileIds[0])}, + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaPhoto { Media = InputFile.FromFileId(fileIds[0])}, + new InputMediaPhoto { Media = InputFile.FromFileId(fileIds[1])}, + new InputMediaPhoto { Media = InputFile.FromFileId(fileIds[0])}, + ] } ); @@ -98,16 +91,18 @@ public async Task Should_Send_3_Photos_Album_Using_FileId() public async Task Should_Send_Photo_Album_Using_Url() { // ToDo add exception: Bad Request: failed to get HTTP URL content - int replyToMessageId = _classFixture.Entities.First().MessageId; + int replyToMessageId = classFixture.Entities.First().MessageId; Message[] messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: new IAlbumInputMedia[] + new() { - new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/06/20/19/22/fuchs-2424369_640.jpg")}, - new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")}, - }, - replyParameters: new() { MessageId = replyToMessageId } + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/06/20/19/22/fuchs-2424369_640.jpg")}, + new InputMediaPhoto { Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg")}, + ], + ReplyParameters = new() { MessageId = replyToMessageId } + } ); Assert.Equal(2, messages.Length); @@ -131,31 +126,31 @@ public async Task Should_Upload_2_Videos_Album() stream2 = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot) ) { - IAlbumInputMedia[] inputMedia = - [ - new InputMediaVideo - { - Media = InputFile.FromStream(stream0, "GoldenRatio.mp4"), - Caption = "Golden Ratio", - Height = 240, - Width = 240, - Duration = 28, - }, - new InputMediaVideo - { - Media = InputFile.FromStream(stream1, "MoonLanding.mp4"), - Caption = "Moon Landing" - }, - new InputMediaPhoto - { - Media = InputFile.FromStream(stream2, "bot.gif"), - Caption = "Bot" - }, - ]; - messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: inputMedia + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaVideo + { + Media = InputFile.FromStream(stream0, "GoldenRatio.mp4"), + Caption = "Golden Ratio", + Height = 240, + Width = 240, + Duration = 28, + }, + new InputMediaVideo + { + Media = InputFile.FromStream(stream1, "MoonLanding.mp4"), + Caption = "Moon Landing" + }, + new InputMediaPhoto + { + Media = InputFile.FromStream(stream2, "bot.gif"), + Caption = "Bot" + }, + ], + } ); } @@ -190,25 +185,25 @@ public async Task Should_Upload_2_Photos_Album_With_Markdown_Encoded_Captions() stream1 = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo), stream2 = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot); - IAlbumInputMedia[] inputMedia = - [ - new InputMediaPhoto - { - Media = InputFile.FromStream(stream1, "logo.png"), - Caption = "*Logo*", - ParseMode = ParseMode.Markdown - }, - new InputMediaPhoto - { - Media = InputFile.FromStream(stream2, "bot.gif"), - Caption = "_Bot_", - ParseMode = ParseMode.Markdown - }, - ]; - Message[] messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: inputMedia + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaPhoto + { + Media = InputFile.FromStream(stream1, "logo.png"), + Caption = "*Logo*", + ParseMode = ParseMode.Markdown + }, + new InputMediaPhoto + { + Media = InputFile.FromStream(stream2, "bot.gif"), + Caption = "_Bot_", + ParseMode = ParseMode.Markdown + }, + ], + } ); Message message1 = messages[0]; @@ -235,23 +230,23 @@ public async Task Should_Video_With_Thumbnail_In_Album() stream1 = System.IO.File.OpenRead(Constants.PathToFile.Videos.GoldenRatio), stream2 = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); - IAlbumInputMedia[] inputMedia = - [ - new InputMediaVideo - { - Media = InputFile.FromStream(stream1, "GoldenRatio.mp4"), - Thumbnail = new InputFileStream(stream2, "thumbnail.jpg"), - SupportsStreaming = true, - }, - new InputMediaPhoto - { - Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg"), - }, - ]; - Message[] messages = await BotClient.SendMediaGroupAsync( - chatId: _fixture.SupergroupChat.Id, - media: inputMedia + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Media = [ + new InputMediaVideo + { + Media = InputFile.FromStream(stream1, "GoldenRatio.mp4"), + Thumbnail = InputFile.FromStream(stream2, "thumbnail.jpg"), + SupportsStreaming = true, + }, + new InputMediaPhoto + { + Media = InputFile.FromUri("https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg"), + }, + ], + } ); Assert.Equal(MessageType.Video, messages[0].Type); diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/AnimationMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/AnimationMessageTests.cs index e7e84cef0..9e7f350f6 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/AnimationMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/AnimationMessageTests.cs @@ -1,6 +1,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -10,16 +11,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendAnimationMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class AnimationMessageTests +public class AnimationMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public AnimationMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send an animation with caption")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendAnimation)] @@ -29,14 +23,17 @@ public async Task Should_Send_Animation() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Animation.Earth)) { message = await BotClient.SendAnimationAsync( - chatId: _fixture.SupergroupChat.Id, - animation: new InputFileStream(stream), - duration: 4, - width: 400, - height: 400, - thumbnail: null, - caption: "Rotating Earth", - parseMode: ParseMode.Html + new() + { + ChatId = fixture.SupergroupChat.Id, + Animation = InputFile.FromStream(stream), + Duration = 4, + Width = 400, + Height = 400, + Thumbnail = null, + Caption = "Rotating Earth", + ParseMode = ParseMode.Html, + } ); } @@ -76,9 +73,12 @@ public async Task Should_Send_Animation_With_Thumb() ) { message = await BotClient.SendAnimationAsync( - chatId: _fixture.SupergroupChat, - animation: new InputFileStream(stream1, "earth.gif"), - thumbnail: new InputFileStream(stream2, "thumb.jpg") + new() + { + ChatId = fixture.SupergroupChat, + Animation = InputFile.FromStream(stream1, "earth.gif"), + Thumbnail = InputFile.FromStream(stream2, "thumb.jpg"), + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/AudioMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/AudioMessageTests.cs index 59962b5ce..11aaaca4e 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/AudioMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/AudioMessageTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -9,16 +10,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendAudioMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class AudioMessageTests +public class AudioMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public AudioMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send an audio with caption")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendAudio)] @@ -33,12 +27,15 @@ public async Task Should_Send_Audio() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.CantinaRagMp3)) { message = await BotClient.SendAudioAsync( - chatId: _fixture.SupergroupChat, - audio: new InputFileStream(stream, "Jackson F Smith - Cantina Rag.mp3"), - title: title, - performer: performer, - caption: caption, - duration: duration + new() + { + ChatId = fixture.SupergroupChat, + Audio = InputFile.FromStream(stream, "Jackson F Smith - Cantina Rag.mp3"), + Title = title, + Performer = performer, + Caption = caption, + Duration = duration, + } ); } @@ -67,9 +64,12 @@ public async Task Should_Send_Audio_With_Thumb() ) { message = await BotClient.SendAudioAsync( - chatId: _fixture.SupergroupChat, - audio: new InputFileStream(stream1, "Ask Again - A State of Despair.mp3"), - thumbnail: new InputFileStream(stream2, "thumb.jpg") + new() + { + ChatId = fixture.SupergroupChat, + Audio = InputFile.FromStream(stream1, "Ask Again - A State of Despair.mp3"), + Thumbnail = InputFile.FromStream(stream2, "thumb.jpg"), + } ); } @@ -93,10 +93,13 @@ public async Task Should_Send_Voice() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.TestOgg)) { message = await BotClient.SendVoiceAsync( - chatId: _fixture.SupergroupChat, - voice: new InputFileStream(stream), - caption: caption, - duration: duration + new() + { + ChatId = fixture.SupergroupChat, + Voice = InputFile.FromStream(stream), + Caption = caption, + Duration = duration, + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs index 8b42027bd..7155c1b54 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/CopyMessageTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -17,15 +18,21 @@ public class CopyMessageTests(TestsFixture testsFixture) [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CopyMessage)] public async Task Should_Copy_Text_Message() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "hello" + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = _fixture.SupergroupChat.Id, + Text = "hello", + } ); MessageId copyMessageId = await BotClient.CopyMessageAsync( - chatId: _fixture.SupergroupChat.Id, - fromChatId: _fixture.SupergroupChat.Id, - messageId: message.MessageId + new() + { + ChatId = _fixture.SupergroupChat.Id, + FromChatId = _fixture.SupergroupChat.Id, + MessageId = message.MessageId, + } ); Assert.NotEqual(0, copyMessageId.Id); @@ -35,22 +42,31 @@ public async Task Should_Copy_Text_Message() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.CopyMessages)] public async Task Should_Copy_Text_Messages() { - Message message1 = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "message one." + Message message1 = await BotClient.SendMessageAsync( + new() + { + ChatId = _fixture.SupergroupChat.Id, + Text = "message one.", + } ); - Message message2 = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "message two" + Message message2 = await BotClient.SendMessageAsync( + new() + { + ChatId = _fixture.SupergroupChat.Id, + Text = "message two", + } ); int[] messageIds = [message1.MessageId, message2.MessageId]; MessageId[] copyMessageIds = await BotClient.CopyMessagesAsync( - chatId: _fixture.SupergroupChat.Id, - fromChatId: _fixture.SupergroupChat.Id, - messageIds: messageIds + new() + { + ChatId = _fixture.SupergroupChat.Id, + FromChatId = _fixture.SupergroupChat.Id, + MessageIds = messageIds, + } ); Assert.Equal(2, copyMessageIds.Length); diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/DocumentMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/DocumentMessageTests.cs index d5ca15142..78bd83c94 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/DocumentMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/DocumentMessageTests.cs @@ -9,16 +9,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendDocumentMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SendingDocumentMessageTests +public class SendingDocumentMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public SendingDocumentMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send a pdf document with caption")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDocument)] @@ -26,9 +19,12 @@ public async Task Should_Send_Pdf_Document() { await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Documents.Hamlet); Message message = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat.Id, - document: new InputFileStream(content: stream, fileName: "HAMLET.pdf"), - caption: "The Tragedy of Hamlet,\nPrince of Denmark" + new() + { + ChatId = fixture.SupergroupChat.Id, + Document = new InputFileStream(content: stream, fileName: "HAMLET.pdf"), + Caption = "The Tragedy of Hamlet,\nPrince of Denmark", + } ); Assert.Equal(MessageType.Document, message.Type); @@ -50,9 +46,12 @@ public async Task Should_Send_Document_With_Farsi_Name() { await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Documents.Hamlet); Message message = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat.Id, - document: new InputFileStream(content: stream, fileName: "هملت.pdf"), - caption: "تراژدی هملت\nشاهزاده دانمارک" + new() + { + ChatId = fixture.SupergroupChat.Id, + Document = new InputFileStream(content: stream, fileName: "هملت.pdf"), + Caption = "تراژدی هملت\nشاهزاده دانمارک", + } ); Assert.Equal(MessageType.Document, message.Type); @@ -75,9 +74,12 @@ public async Task Should_Send_Document_With_Thumb() thumbStream = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.TheAbilityToBreak); Message message = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileStream(content: documentStream, fileName: "Hamlet.pdf"), - thumbnail: new InputFileStream(content: thumbStream, fileName: "thumb.jpg") + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromStream(documentStream, "Hamlet.pdf"), + Thumbnail = InputFile.FromStream(thumbStream, "thumb.jpg"), + } ); Assert.NotNull(message.Document); diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingContactMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingContactMessageTests.cs index 3affd384b..021425eca 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingContactMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingContactMessageTests.cs @@ -8,16 +8,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendContactMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SendingContactMessageTests +public class SendingContactMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public SendingContactMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send a contact")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendContact)] @@ -28,10 +21,13 @@ public async Task Should_Send_Contact() const string lastName = "Solo"; Message message = await BotClient.SendContactAsync( - chatId: _fixture.SupergroupChat, - phoneNumber: phoneNumber, - firstName: firstName, - lastName: lastName + new() + { + ChatId = fixture.SupergroupChat, + PhoneNumber = phoneNumber, + FirstName = firstName, + LastName = lastName, + } ); Assert.Equal(MessageType.Contact, message.Type); @@ -45,31 +41,36 @@ public async Task Should_Send_Contact() public async Task Should_Send_Contact_With_VCard() { const string vcard = - "BEGIN:VCARD" + "\n" + - "VERSION:2.1" + "\n" + - "N:Gump;Forrest;;Mr." + "\n" + - "FN:Forrest Gump" + "\n" + - "ORG:Bubba Gump Shrimp Co." + "\n" + - "TITLE:Shrimp Man" + "\n" + - "PHOTO;JPEG:https://upload.wikimedia.org/wikipedia/commons/9/95/TomHanksForrestGump94.jpg" + "\n" + - "TEL;WORK;VOICE:(111) 555-1212" + "\n" + - "TEL;HOME;VOICE:(404) 555-1212" + "\n" + - "ADR;HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America" + "\n" + - "LABEL;HOME;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:42 Plantation St.=0D=0A=" + "\n" + - " Baytown, LA 30314=0D=0AUnited States of America" + "\n" + - "EMAIL:forrestgump@example.org" + "\n" + - "REV:20080424T195243Z" + "\n" + - "END:VCARD"; + """ + BEGIN:VCARD + VERSION:2.1 + N:Gump;Forrest;;Mr. + FN:Forrest Gump + ORG:Bubba Gump Shrimp Co. + TITLE:Shrimp Man + PHOTO;JPEG:https://upload.wikimedia.org/wikipedia/commons/9/95/TomHanksForrestGump94.jpg + TEL;WORK;VOICE:(111) 555-1212 + TEL;HOME;VOICE:(404) 555-1212 + ADR;HOME:;;42 Plantation St.;Baytown;LA;30314;United States of America + LABEL;HOME;ENCODING=QUOTED-PRINTABLE;CHARSET=UTF-8:42 Plantation St.=0D=0A= + Baytown, LA 30314=0D=0AUnited States of America + EMAIL:forrestgump@example.org + REV:20080424T195243Z + END:VCARD + """; Message message = await BotClient.SendContactAsync( - chatId: _fixture.SupergroupChat, - phoneNumber: "+11115551212", - firstName: "Forrest", - vCard: vcard + new() + { + ChatId = fixture.SupergroupChat, + PhoneNumber = "+11115551212", + FirstName = "Forrest", + Vcard = vcard, + } ); Assert.Equal(MessageType.Contact, message.Type); Assert.NotNull(message.Contact); Assert.Equal(vcard, message.Contact.Vcard); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingPhotoMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingPhotoMessageTests.cs index 515c60eb0..0569af970 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingPhotoMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingPhotoMessageTests.cs @@ -13,19 +13,10 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendPhotoMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SendingPhotoMessageTests : IClassFixture> +public class SendingPhotoMessageTests(TestsFixture fixture, EntityFixture classFixture) + : IClassFixture> { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - readonly EntityFixture _classFixture; - - public SendingPhotoMessageTests(TestsFixture fixture, EntityFixture classFixture) - { - _fixture = fixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should Send photo using a file")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendPhoto)] @@ -33,9 +24,12 @@ public async Task Should_Send_Photo_File() { await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot); Message message = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat.Id, - photo: new InputFileStream(stream), - caption: "👆 This is a\nTelegram Bot" + new() + { + ChatId = fixture.SupergroupChat.Id, + Photo = InputFile.FromStream(stream), + Caption = "👆 This is a\nTelegram Bot", + } ); Assert.Equal(MessageType.Photo, message.Type); @@ -47,18 +41,21 @@ public async Task Should_Send_Photo_File() Assert.All(message.Photo.Select(ps => ps.Height), h => Assert.NotEqual(default, h)); Assert.NotNull(message.From); - _classFixture.Entity = message; + classFixture.Entity = message; } [OrderedFact("Should Send previous photo using its file_id")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendPhoto)] public async Task Should_Send_Photo_FileId() { - string fileId = _classFixture.Entity.Photo!.First().FileId; + string fileId = classFixture.Entity.Photo!.First().FileId; Message message = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat.Id, - photo: new InputFileId(fileId) + new() + { + ChatId = fixture.SupergroupChat.Id, + Photo = InputFile.FromFileId(fileId), + } ); // Apparently file ids of photos no longer remain the same when sending them @@ -73,7 +70,7 @@ public async Task Should_Send_Photo_FileId() public async Task Should_Parse_Message_Caption_Entities_Into_Values() { (MessageEntityType Type, string Value)[] entityValueMappings = - { + [ (MessageEntityType.PhoneNumber, "+38612345678"), (MessageEntityType.Cashtag, "$EUR"), (MessageEntityType.Hashtag, "#TelegramBots"), @@ -81,14 +78,17 @@ public async Task Should_Parse_Message_Caption_Entities_Into_Values() (MessageEntityType.Url, "https://github.com/TelegramBots"), (MessageEntityType.Email, "security@telegram.org"), (MessageEntityType.BotCommand, "/test"), - (MessageEntityType.BotCommand, $"/test@{_fixture.BotUser.Username}"), - }; + (MessageEntityType.BotCommand, $"/test@{fixture.BotUser.Username}") + ]; await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); Message message = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat.Id, - photo: new InputFileStream(stream), - caption: string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)) + new() + { + ChatId = fixture.SupergroupChat.Id, + Photo = InputFile.FromStream(stream), + Caption = string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)), + } ); Assert.NotNull(message.CaptionEntities); @@ -104,18 +104,21 @@ public async Task Should_Parse_Message_Caption_Entities_Into_Values() public async Task Should_Send_Photo_With_Markdown_Encoded_Caption() { (MessageEntityType Type, string EntityBody, string EncodedEntity)[] entityValueMappings = - { + [ (MessageEntityType.Bold, "bold", "*bold*"), (MessageEntityType.Italic, "italic", "_italic_"), - (MessageEntityType.TextLink, "Text Link", "[Text Link](https://github.com/TelegramBots)"), - }; + (MessageEntityType.TextLink, "Text Link", "[Text Link](https://github.com/TelegramBots)") + ]; await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Logo); Message message = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat.Id, - photo: new InputFileStream(stream), - caption: string.Join("\n", entityValueMappings.Select(tuple => tuple.EncodedEntity)), - parseMode: ParseMode.Markdown + new() + { + ChatId = fixture.SupergroupChat.Id, + Photo = InputFile.FromStream(stream), + Caption = string.Join("\n", entityValueMappings.Select(tuple => tuple.EncodedEntity)), + ParseMode = ParseMode.Markdown, + } ); Assert.NotNull(message.CaptionEntities); @@ -130,11 +133,14 @@ public async Task Should_Send_Photo_With_Markdown_Encoded_Caption() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendPhoto)] public async Task Should_Send_Deserialized_Photo_Request() { - string json = $@"{{ - chat_id: ""{_fixture.SupergroupChat.Id}"", - photo: ""https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg"", - caption: ""Photo request deserialized from JSON"", - }}"; + string json = + $$""" + { + chat_id: "{{fixture.SupergroupChat.Id}}", + photo: "https://cdn.pixabay.com/photo/2017/04/11/21/34/giraffe-2222908_640.jpg", + caption: "Photo request deserialized from JSON", + } + """; SendPhotoRequest request = JsonConvert.DeserializeObject(json); diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingVenueMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingVenueMessageTests.cs index 268253a4a..2ee87f7bb 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingVenueMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/SendingVenueMessageTests.cs @@ -10,16 +10,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendVenueMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SendingVenueMessageTests +public class SendingVenueMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public SendingVenueMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send a venue")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVenue)] @@ -32,12 +25,15 @@ public async Task Should_Send_Venue() const string foursquareId = "4cc6222106c25481d7a4a047"; Message message = await BotClient.SendVenueAsync( - chatId: _fixture.SupergroupChat, - latitude: lat, - longitude: lon, - title: title, - address: address, - foursquareId: foursquareId + new() + { + ChatId = fixture.SupergroupChat, + Latitude = lat, + Longitude = lon, + Title = title, + Address = address, + FoursquareId = foursquareId, + } ); Assert.Equal(MessageType.Venue, message.Type); @@ -53,15 +49,18 @@ public async Task Should_Send_Venue() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVenue)] public async Task Should_Deserialize_Send_Venue() { - string json = $@"{{ - chat_id: ""{_fixture.SupergroupChat.Id}"", + string json = + $$""" + { + chat_id: "{{fixture.SupergroupChat.Id}}", latitude: 48.204296, longitude: 16.365514, - title: ""Burggarten"", - address: ""Opernring"", - foursquare_id: ""4b7ff7c3f964a5208d4730e3"", - foursquare_type: ""parks_outdoors/park"" - }}"; + title: "Burggarten", + address: "Opernring", + foursquare_id: "4b7ff7c3f964a5208d4730e3", + foursquare_type: "parks_outdoors/park" + } + """; SendVenueRequest request = JsonConvert.DeserializeObject(json); @@ -76,4 +75,4 @@ public async Task Should_Deserialize_Send_Venue() Assert.InRange(message.Venue.Location.Latitude, 48.204296 - 0.001f, 48.204296 + 0.001f); Assert.InRange(message.Venue.Location.Longitude, 16.365514 - 0.001f, 16.365514 + 0.001f); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs index dbea109b9..9555d3fa4 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/TextMessageTests.cs @@ -13,76 +13,79 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendTextMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class TextMessageTests : IClassFixture +public class TextMessageTests(TestsFixture testsFixture, TextMessageTests.Fixture classFixture) + : IClassFixture { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - readonly Fixture _classFixture; - - public TextMessageTests(TestsFixture testsFixture, Fixture classFixture) - { - _fixture = testsFixture; - _classFixture = classFixture; - } + ITelegramBotClient BotClient => testsFixture.BotClient; [OrderedFact("Should send text message")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Send_Text_Message() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Hello world!" + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = "Hello world!", + } ); Assert.Equal("Hello world!", message.Text); Assert.Equal(MessageType.Text, message.Type); - Assert.Equal(_fixture.SupergroupChat.Id.ToString(), message.Chat.Id.ToString()); + Assert.Equal(testsFixture.SupergroupChat.Id.ToString(), message.Chat.Id.ToString()); Assert.InRange(message.Date, DateTime.UtcNow.AddSeconds(-10), DateTime.UtcNow.AddSeconds(2)); Assert.NotNull(message.From); - Assert.Equal(_fixture.BotUser.Id, message.From.Id); - Assert.Equal(_fixture.BotUser.Username, message.From.Username); + Assert.Equal(testsFixture.BotUser.Id, message.From.Id); + Assert.Equal(testsFixture.BotUser.Username, message.From.Username); // getMe request returns more information than is present in received updates - Asserts.UsersEqual(_fixture.BotUser, message.From); + Asserts.UsersEqual(testsFixture.BotUser, message.From); } [OrderedFact("Should send text message to channel")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Send_Text_Message_To_Channel() { - string text = $"Hello members of channel {_classFixture.ChannelChatId}"; + string text = $"Hello members of channel {classFixture.ChannelChatId}"; - Message message = await BotClient.SendTextMessageAsync( - chatId: _classFixture.ChannelChatId, - text: text + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = classFixture.ChannelChatId, + Text = text, + } ); Assert.Equal(text, message.Text); Assert.Equal(MessageType.Text, message.Type); - Assert.Equal(_classFixture.ChannelChat.Id, message.Chat.Id); - Assert.Equal(_classFixture.ChannelChat.Username, message.Chat.Username); + Assert.Equal(classFixture.ChannelChat.Id, message.Chat.Id); + Assert.Equal(classFixture.ChannelChat.Username, message.Chat.Username); } [OrderedFact("Should forward a message to same chat")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.ForwardMessage)] public async Task Should_Forward_Message() { - Message message1 = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat, - text: "➡️ Message to be forwared ⬅️" + Message message1 = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = "➡️ Message to be forwared ⬅️", + } ); Message message2 = await BotClient.ForwardMessageAsync( - chatId: _fixture.SupergroupChat, - fromChatId: _fixture.SupergroupChat, - messageId: message1.MessageId + new() + { + ChatId = testsFixture.SupergroupChat, + FromChatId = testsFixture.SupergroupChat, + MessageId = message1.MessageId, + } ); MessageOriginUser forwardOrigin = (MessageOriginUser)message2.ForwardOrigin; Assert.NotNull(forwardOrigin); - Asserts.UsersEqual(_fixture.BotUser, forwardOrigin.SenderUser); + Asserts.UsersEqual(testsFixture.BotUser, forwardOrigin.SenderUser); Assert.InRange( forwardOrigin.Date, DateTime.UtcNow.AddSeconds(-20), @@ -103,24 +106,27 @@ public async Task Should_Parse_MarkDown_Entities() {MessageEntityType.TextLink, $"[inline url to Telegram.org]({url})"}, { MessageEntityType.TextMention, - $"[{_fixture.BotUser.GetSafeUsername()}](tg://user?id={_fixture.BotUser.Id})" + $"[{testsFixture.BotUser.GetSafeUsername()}](tg://user?id={testsFixture.BotUser.Id})" }, {MessageEntityType.Code, @"inline ""`fixed-width code`"""}, {MessageEntityType.Pre, "```pre-formatted fixed-width code block```"}, }; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: string.Join("\n", entityValueMappings.Values), - parseMode: ParseMode.Markdown, - linkPreviewOptions: new() { IsDisabled = true } + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = string.Join("\n", entityValueMappings.Values), + ParseMode = ParseMode.Markdown, + LinkPreviewOptions = new() { IsDisabled = true }, + } ); Assert.NotNull(message.Entities); Assert.Equal(entityValueMappings.Keys, message.Entities.Select(e => e.Type)); Assert.Equal(url, message.Entities.Single(e => e.Type == MessageEntityType.TextLink).Url); Asserts.UsersEqual( - _fixture.BotUser, + testsFixture.BotUser, message.Entities.Single(e => e.Type == MessageEntityType.TextMention).User ); } @@ -139,7 +145,7 @@ public async Task Should_Parse_HTML_Entities() (MessageEntityType.TextLink, $@"inline url to Telegram.org"), ( MessageEntityType.TextMention, - $@"{_fixture.BotUser.Username}" + $@"{testsFixture.BotUser.Username}" ), (MessageEntityType.Code, @"inline ""fixed-width code"""), (MessageEntityType.Pre, "
pre-formatted fixed-width code block
"), @@ -148,11 +154,14 @@ public async Task Should_Parse_HTML_Entities() (MessageEntityType.Spoiler, "spoiler"), ]; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)), - parseMode: ParseMode.Html, - linkPreviewOptions: new() { IsDisabled = true } + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)), + ParseMode = ParseMode.Html, + LinkPreviewOptions = new() { IsDisabled = true }, + } ); Assert.NotNull(message.Entities); @@ -162,7 +171,7 @@ public async Task Should_Parse_HTML_Entities() ); Assert.Equal(url, message.Entities.Single(e => e.Type == MessageEntityType.TextLink).Url); Asserts.UsersEqual( - _fixture.BotUser, + testsFixture.BotUser, message.Entities.Single(e => e.Type == MessageEntityType.TextMention).User ); } @@ -180,12 +189,15 @@ public async Task Should_Parse_Message_Entities_Into_Values() (MessageEntityType.Url, "https://github.com/TelegramBots"), (MessageEntityType.Email, "security@telegram.org"), (MessageEntityType.BotCommand, "/test"), - (MessageEntityType.BotCommand, $"/test@{_fixture.BotUser.Username}"), + (MessageEntityType.BotCommand, $"/test@{testsFixture.BotUser.Username}"), ]; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)) + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = string.Join("\n", entityValueMappings.Select(tuple => tuple.Value)), + } ); Assert.NotNull(message.Entities); @@ -209,7 +221,7 @@ public async Task Should_Parse_MarkdownV2_Entities() {MessageEntityType.TextLink, $"[inline url to Telegram\\.org]({url})"}, { MessageEntityType.TextMention, - $"[{_fixture.BotUser.GetSafeUsername()}](tg://user?id={_fixture.BotUser.Id})" + $"[{testsFixture.BotUser.GetSafeUsername()}](tg://user?id={testsFixture.BotUser.Id})" }, {MessageEntityType.Code, @"inline ""`fixed-width code`"""}, {MessageEntityType.Pre, "```pre-formatted fixed-width code block```"}, @@ -218,18 +230,21 @@ public async Task Should_Parse_MarkdownV2_Entities() {MessageEntityType.Spoiler, "||spoiler||"}, }; - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: string.Join("\n", entityValueMappings.Values), - parseMode: ParseMode.MarkdownV2, - linkPreviewOptions: new() { IsDisabled = true } + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = string.Join("\n", entityValueMappings.Values), + ParseMode = ParseMode.MarkdownV2, + LinkPreviewOptions = new() { IsDisabled = true }, + } ); Assert.NotNull(message.Entities); Assert.Equal(entityValueMappings.Keys, message.Entities.Select(e => e.Type)); Assert.Equal(url, message.Entities.Single(e => e.Type == MessageEntityType.TextLink).Url); Asserts.UsersEqual( - _fixture.BotUser, + testsFixture.BotUser, message.Entities.Single(e => e.Type == MessageEntityType.TextMention).User ); } @@ -238,49 +253,57 @@ public async Task Should_Parse_MarkdownV2_Entities() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Send_Message_With_Protected_Content() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "This content is protected!", - protectContent: true + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = "This content is protected!", + ProtectContent = true, + } ); Assert.Equal("This content is protected!", message.Text); Assert.Equal(MessageType.Text, message.Type); - Assert.Equal(_fixture.SupergroupChat.Id.ToString(), message.Chat.Id.ToString()); + Assert.Equal(testsFixture.SupergroupChat.Id.ToString(), message.Chat.Id.ToString()); Assert.InRange(message.Date, DateTime.UtcNow.AddSeconds(-10), DateTime.UtcNow.AddSeconds(2)); Assert.NotNull(message.From); - Assert.Equal(_fixture.BotUser.Id, message.From.Id); - Assert.Equal(_fixture.BotUser.Username, message.From.Username); + Assert.Equal(testsFixture.BotUser.Id, message.From.Id); + Assert.Equal(testsFixture.BotUser.Username, message.From.Username); Assert.True(message.HasProtectedContent); // getMe request returns more information than is present in received updates - Asserts.UsersEqual(_fixture.BotUser, message.From); + Asserts.UsersEqual(testsFixture.BotUser, message.From); } [OrderedFact("Should send a message with protected content")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] public async Task Should_Receive_Error_Trying_Forward_A_Message__With_Protected_Content() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "This content is protected!", - protectContent: true + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat.Id, + Text = "This content is protected!", + ProtectContent = true, + } ); Assert.True(message.HasProtectedContent); ApiRequestException exception = await Assert.ThrowsAsync( async () => await BotClient.ForwardMessageAsync( - fromChatId: _fixture.SupergroupChat.Id, - chatId: _fixture.SupergroupChat.Id, - messageId: message.MessageId + new() + { + FromChatId = testsFixture.SupergroupChat.Id, + ChatId = testsFixture.SupergroupChat.Id, + MessageId = message.MessageId, + } ) ); Assert.Equal(400, exception.ErrorCode); } - public class Fixture(TestsFixture testsFixture) : ChannelChatFixture(testsFixture, Constants.TestCollections.SendTextMessage) - { - } + public class Fixture(TestsFixture testsFixture) + : ChannelChatFixture(testsFixture, Constants.TestCollections.SendTextMessage); } diff --git a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs index d6e7708da..d445dd0a9 100644 --- a/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Sending Messages/VideoMessageTests.cs @@ -11,16 +11,9 @@ namespace Telegram.Bot.Tests.Integ.Sending_Messages; [Collection(Constants.TestCollections.SendVideoMessage)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class SendingVideoMessageTests +public class SendingVideoMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public SendingVideoMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should send a video with caption")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVideo)] @@ -30,12 +23,15 @@ public async Task Should_Send_Video() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Videos.MoonLanding)) { message = await BotClient.SendVideoAsync( - chatId: _fixture.SupergroupChat.Id, - video: new InputFileStream(stream, "moon-landing.mp4"), - duration: 104, - width: 320, - height: 240, - caption: "Moon Landing" + new() + { + ChatId = fixture.SupergroupChat.Id, + Video = InputFile.FromStream(stream, "moon-landing.mp4"), + Duration = 104, + Width = 320, + Height = 240, + Caption = "Moon Landing", + } ); } @@ -67,10 +63,13 @@ public async Task Should_Send_Video_Note() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Videos.GoldenRatio)) { message = await BotClient.SendVideoNoteAsync( - chatId: _fixture.SupergroupChat.Id, - videoNote: new InputFileStream(stream), - duration: 28, - length: 240 + new() + { + ChatId = fixture.SupergroupChat.Id, + VideoNote = InputFile.FromStream(stream), + Duration = 28, + Length = 240, + } ); } @@ -100,9 +99,12 @@ public async Task Should_Send_Video_With_Thumb() ) { message = await BotClient.SendVideoAsync( - chatId: _fixture.SupergroupChat, - video: new InputFileStream(stream1), - thumbnail: new InputFileStream(stream2, "thumb.jpg") + new() + { + ChatId = fixture.SupergroupChat, + Video = InputFile.FromStream(stream1), + Thumbnail = InputFile.FromStream(stream2, "thumb.jpg"), + } ); } @@ -127,9 +129,12 @@ public async Task Should_Send_Video_Note_With_Thumb() ) { message = await BotClient.SendVideoNoteAsync( - chatId: _fixture.SupergroupChat.Id, - videoNote: new InputFileStream(stream1), - thumbnail: new InputFileStream(stream2, "thumbnail.jpg") + new() + { + ChatId = fixture.SupergroupChat.Id, + VideoNote = InputFile.FromStream(stream1), + Thumbnail = InputFile.FromStream(stream2, "thumbnail.jpg"), + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs index c941f233b..34a40f2d1 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -13,19 +14,10 @@ namespace Telegram.Bot.Tests.Integ.Stickers; [Collection(Constants.TestCollections.Stickers)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class StickersTests : IClassFixture +public class StickersTests(TestsFixture fixture, StickersTestsFixture classFixture) + : IClassFixture { - private ITelegramBotClient BotClient => _fixture.BotClient; - - private readonly StickersTestsFixture _stickersTestsFixture; - - private readonly TestsFixture _fixture; - - public StickersTests(TestsFixture fixture, StickersTestsFixture classFixture) - { - _stickersTestsFixture = classFixture; - _fixture = fixture; - } + private ITelegramBotClient BotClient => fixture.BotClient; #region 1. Upload sticker files [OrderedFact("Should upload static sticker file")] @@ -35,15 +27,18 @@ public async Task Should_Upload_Static_Sticker_File() await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.StaticFirst); File file = await BotClient.UploadStickerFileAsync( - userId: _stickersTestsFixture.OwnerUserId, - sticker: new(stream), - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Sticker = new(stream), + StickerFormat = StickerFormat.Static, + } ); Assert.NotEmpty(file.FileId); Assert.True(file.FileSize > 0); - _stickersTestsFixture.TestUploadedStaticStickerFile = file; + classFixture.TestUploadedStaticStickerFile = file; } [OrderedFact("Should upload animated sticker file")] @@ -53,15 +48,18 @@ public async Task Should_Upload_Animated_Sticker_File() await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.AnimatedFirst); File file = await BotClient.UploadStickerFileAsync( - userId: _stickersTestsFixture.OwnerUserId, - sticker: new(stream), - stickerFormat: StickerFormat.Animated + new() + { + UserId = classFixture.OwnerUserId, + Sticker = InputFile.FromStream(stream), + StickerFormat = StickerFormat.Animated, + } ); Assert.NotEmpty(file.FileId); Assert.True(file.FileSize > 0); - _stickersTestsFixture.TestUploadedAnimatedStickerFile = file; + classFixture.TestUploadedAnimatedStickerFile = file; } [OrderedFact("Should upload video sticker file")] @@ -71,15 +69,18 @@ public async Task Should_Upload_Video_Sticker_File() await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.Regular.VideoFirst); File file = await BotClient.UploadStickerFileAsync( - userId: _stickersTestsFixture.OwnerUserId, - sticker: new(stream), - stickerFormat: StickerFormat.Video + new() + { + UserId = classFixture.OwnerUserId, + Sticker = InputFile.FromStream(stream), + StickerFormat = StickerFormat.Video, + } ); Assert.NotEmpty(file.FileId); Assert.True(file.FileSize > 0); - _stickersTestsFixture.TestUploadedVideoStickerFile = file; + classFixture.TestUploadedVideoStickerFile = file; } #endregion @@ -96,33 +97,36 @@ public async Task Should_Create_New_Static_Sticker_Set() List inputStickers = [ new( - sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromFileId(classFixture.TestUploadedStaticStickerFile.FileId), + emojiList: classFixture.FirstEmojis ), new( - sticker: new InputFileStream(stream, "Static2.webp"), - emojiList: _stickersTestsFixture.SecondEmojis + sticker: InputFile.FromStream(stream, "Static2.webp"), + emojiList: classFixture.SecondEmojis ), ]; await BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static, - stickerType: StickerType.Regular + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + StickerType = StickerType.Regular, + } ); await Task.Delay(1_000); - _stickersTestsFixture.TestStaticRegularStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + classFixture.TestStaticRegularStickerSet = await BotClient.GetStickerSetAsync( + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); - Assert.False(_stickersTestsFixture.TestStaticRegularStickerSet.IsAnimated); - Assert.False(_stickersTestsFixture.TestStaticRegularStickerSet.IsVideo); - Assert.Equal(2, _stickersTestsFixture.TestStaticRegularStickerSet.Stickers.Length); + Assert.False(classFixture.TestStaticRegularStickerSet.IsAnimated); + Assert.False(classFixture.TestStaticRegularStickerSet.IsVideo); + Assert.Equal(2, classFixture.TestStaticRegularStickerSet.Stickers.Length); } [OrderedFact("Should create new animated sticker set")] @@ -136,33 +140,36 @@ public async Task Should_Create_New_Animated_Sticker_Set() List inputStickers = [ new( - sticker: new InputFileId(_stickersTestsFixture.TestUploadedAnimatedStickerFile.FileId), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromFileId(classFixture.TestUploadedAnimatedStickerFile.FileId), + emojiList: classFixture.FirstEmojis ), new( - sticker: new InputFileStream(stream, "Animated2.webp"), - emojiList: _stickersTestsFixture.SecondEmojis + sticker: InputFile.FromStream(stream, "Animated2.webp"), + emojiList: classFixture.SecondEmojis ), ]; await BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Animated, - stickerType: StickerType.Regular + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestAnimatedRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Animated, + StickerType = StickerType.Regular, + } ); await Task.Delay(1_000); - _stickersTestsFixture.TestAnimatedRegularStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName + classFixture.TestAnimatedRegularStickerSet = await BotClient.GetStickerSetAsync( + new GetStickerSetRequest { Name = classFixture.TestAnimatedRegularStickerSetName } ); - Assert.True(_stickersTestsFixture.TestAnimatedRegularStickerSet.IsAnimated); - Assert.False(_stickersTestsFixture.TestAnimatedRegularStickerSet.IsVideo); - Assert.Equal(2, _stickersTestsFixture.TestAnimatedRegularStickerSet.Stickers.Length); + Assert.True(classFixture.TestAnimatedRegularStickerSet.IsAnimated); + Assert.False(classFixture.TestAnimatedRegularStickerSet.IsVideo); + Assert.Equal(2, classFixture.TestAnimatedRegularStickerSet.Stickers.Length); } [OrderedFact("Should create new video sticker set")] @@ -176,33 +183,36 @@ public async Task Should_Create_New_Video_Sticker_Set() List inputStickers = [ new( - sticker: new InputFileId(_stickersTestsFixture.TestUploadedVideoStickerFile.FileId), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromFileId(classFixture.TestUploadedVideoStickerFile.FileId), + emojiList: classFixture.FirstEmojis ), new( - sticker: new InputFileStream(stream, "Video2.webp"), - emojiList: _stickersTestsFixture.SecondEmojis + sticker: InputFile.FromStream(stream, "Video2.webp"), + emojiList: classFixture.SecondEmojis ), ]; await BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestVideoRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Video, - stickerType: StickerType.Regular + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestVideoRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Video, + StickerType = StickerType.Regular, + } ); await Task.Delay(1_000); - _stickersTestsFixture.TestVideoRegularStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestVideoRegularStickerSetName + classFixture.TestVideoRegularStickerSet = await BotClient.GetStickerSetAsync( + new GetStickerSetRequest { Name = classFixture.TestVideoRegularStickerSetName } ); - Assert.False(_stickersTestsFixture.TestVideoRegularStickerSet.IsAnimated); - Assert.True(_stickersTestsFixture.TestVideoRegularStickerSet.IsVideo); - Assert.Equal(2, _stickersTestsFixture.TestVideoRegularStickerSet.Stickers.Length); + Assert.False(classFixture.TestVideoRegularStickerSet.IsAnimated); + Assert.True(classFixture.TestVideoRegularStickerSet.IsVideo); + Assert.Equal(2, classFixture.TestVideoRegularStickerSet.Stickers.Length); } #endregion @@ -213,7 +223,7 @@ await BotClient.CreateNewStickerSetAsync( public async Task Should_Send_Static_Sticker() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Assert.False(stickerSet.IsAnimated); @@ -222,13 +232,16 @@ public async Task Should_Send_Static_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(classFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); Message stickerMessage = await BotClient.SendStickerAsync( - chatId: _fixture.SupergroupChat.Id, - sticker: new InputFileId(firstSticker.FileId) + new() + { + ChatId = fixture.SupergroupChat.Id, + Sticker = InputFile.FromFileId(firstSticker.FileId), + } ); Assert.Equal(MessageType.Sticker, stickerMessage.Type); @@ -257,7 +270,7 @@ public async Task Should_Send_Static_Sticker() public async Task Should_Send_Animated_Sticker() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestAnimatedRegularStickerSetName } ); Assert.True(stickerSet.IsAnimated); @@ -266,13 +279,16 @@ public async Task Should_Send_Animated_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(classFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); Message stickerMessage = await BotClient.SendStickerAsync( - chatId: _fixture.SupergroupChat.Id, - sticker: new InputFileId(firstSticker.FileId) + new() + { + ChatId = fixture.SupergroupChat.Id, + Sticker = InputFile.FromFileId(firstSticker.FileId), + } ); Assert.Equal(MessageType.Sticker, stickerMessage.Type); @@ -301,7 +317,7 @@ public async Task Should_Send_Animated_Sticker() public async Task Should_Send_Video_Sticker() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestVideoRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestVideoRegularStickerSetName } ); Assert.False(stickerSet.IsAnimated); @@ -310,16 +326,20 @@ public async Task Should_Send_Video_Sticker() Sticker firstSticker = stickerSet.Stickers.First(); - string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(classFixture.FirstEmojis); Assert.Equal(firstEmojisString, firstSticker.Emoji); Message stickerMessage = await BotClient.SendStickerAsync( - chatId: _fixture.SupergroupChat.Id, - sticker: new InputFileId(firstSticker.FileId) + new() + { + ChatId = fixture.SupergroupChat.Id, + Sticker = InputFile.FromFileId(firstSticker.FileId), + } ); Assert.Equal(MessageType.Sticker, stickerMessage.Type); + Assert.NotNull(stickerMessage.Sticker); Assert.Equal(firstSticker.FileUniqueId, stickerMessage.Sticker.FileUniqueId); Assert.Equal(firstSticker.FileSize, stickerMessage.Sticker.FileSize); Assert.Equal(firstSticker.Type, stickerMessage.Sticker.Type); @@ -348,20 +368,23 @@ public async Task Should_Add_Sticker_To_Static_Sticker_Set() ); InputSticker inputSticker = new( - sticker: new InputFileStream(stream, "Static3.png"), - emojiList: _stickersTestsFixture.ThirdEmojis + sticker: InputFile.FromStream(stream, "Static3.png"), + emojiList: classFixture.ThirdEmojis ); await BotClient.AddStickerToSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - sticker: inputSticker + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticRegularStickerSetName, + Sticker = inputSticker, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Assert.False(stickerSet.IsAnimated); @@ -370,7 +393,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(classFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -387,20 +410,23 @@ public async Task Should_Add_Sticker_To_Animated_Sticker_Set() ); InputSticker inputSticker = new( - sticker: new InputFileStream(stream, "Animated3.tgs"), - emojiList: _stickersTestsFixture.ThirdEmojis + sticker: InputFile.FromStream(stream, "Animated3.tgs"), + emojiList: classFixture.ThirdEmojis ); await BotClient.AddStickerToSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName, - sticker: inputSticker + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestAnimatedRegularStickerSetName, + Sticker = inputSticker, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestAnimatedRegularStickerSetName } ); Assert.True(stickerSet.IsAnimated); @@ -409,7 +435,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(classFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.True(thirdSticker.IsAnimated); @@ -426,20 +452,23 @@ public async Task Should_Add_Sticker_To_Video_Sticker_Set() ); InputSticker inputSticker = new( - sticker: new InputFileStream(stream, "Video3.webm"), - emojiList: _stickersTestsFixture.ThirdEmojis + sticker: InputFile.FromStream(stream, "Video3.webm"), + emojiList: classFixture.ThirdEmojis ); await BotClient.AddStickerToSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestVideoRegularStickerSetName, - sticker: inputSticker + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestVideoRegularStickerSetName, + Sticker = inputSticker, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestVideoRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestVideoRegularStickerSetName } ); Assert.False(stickerSet.IsAnimated); @@ -448,7 +477,7 @@ await BotClient.AddStickerToSetAsync( Sticker thirdSticker = stickerSet.Stickers[2]; - string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(classFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, thirdSticker.Emoji); Assert.False(thirdSticker.IsAnimated); @@ -463,20 +492,23 @@ await BotClient.AddStickerToSetAsync( public async Task Should_Change_Sticker_Position_In_Set() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker thirdSticker = stickerSet.Stickers[2]; await BotClient.SetStickerPositionInSetAsync( - sticker: new(thirdSticker.FileId), - position: 0 + new() + { + Sticker = InputFile.FromFileId(thirdSticker.FileId), + Position = 0, + } ); await Task.Delay(1_000); StickerSet positionedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker firstStickerInPositionedStickerSet = positionedStickerSet.Stickers.First(); @@ -492,19 +524,20 @@ await BotClient.SetStickerPositionInSetAsync( public async Task Should_Delete_Sticker_From_Set() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker thirdSticker = stickerSet.Stickers[2]; await BotClient.DeleteStickerFromSetAsync( - sticker: new(thirdSticker.FileId) + new DeleteStickerFromSetRequest { Sticker = InputFile.FromFileId(thirdSticker.FileId )} + ); await Task.Delay(1_000); StickerSet updatedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Assert.DoesNotContain(updatedStickerSet.Stickers, s => s.FileId == thirdSticker.FileId); @@ -518,29 +551,32 @@ await BotClient.DeleteStickerFromSetAsync( public async Task Should_Set_First_Sticker_EmojiList() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker firstSticker = stickerSet.Stickers.First(); - string thirdEmojisString = string.Concat(_stickersTestsFixture.ThirdEmojis); + string thirdEmojisString = string.Concat(classFixture.ThirdEmojis); Assert.Equal(thirdEmojisString, firstSticker.Emoji); await BotClient.SetStickerEmojiListAsync( - sticker: new(firstSticker.FileId), - emojiList: _stickersTestsFixture.FirstEmojis + new() + { + Sticker = InputFile.FromFileId(firstSticker.FileId), + EmojiList = classFixture.FirstEmojis, + } ); await Task.Delay(1_000); StickerSet updatedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker updatedFirstSticker = updatedStickerSet.Stickers.First(); - string firstEmojisString = string.Concat(_stickersTestsFixture.FirstEmojis); + string firstEmojisString = string.Concat(classFixture.FirstEmojis); Assert.Equal(firstEmojisString, updatedFirstSticker.Emoji); } @@ -555,21 +591,27 @@ public async Task Should_Set_First_Sticker_Keywords() string[] keywords = ["test", "supertest"]; StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Sticker firstSticker = stickerSet.Stickers.First(); await BotClient.SetStickerKeywordsAsync( - sticker: new(firstSticker.FileId), - keywords: keywords + new SetStickerKeywordsRequest + { + Sticker = InputFile.FromFileId(firstSticker.FileId), + Keywords = keywords, + } ); await Task.Delay(1_000); await BotClient.SetStickerKeywordsAsync( - sticker: new(firstSticker.FileId), - keywords: null + new SetStickerKeywordsRequest + { + Sticker = InputFile.FromFileId(firstSticker.FileId), + Keywords = null, + } ); } #endregion @@ -583,14 +625,17 @@ public async Task Should_Set_Sticker_Set_Title() const string newStickerSetTitle = "New title for sticker set"; await BotClient.SetStickerSetTitleAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - title: newStickerSetTitle + new() + { + Name = classFixture.TestStaticRegularStickerSetName, + Title = newStickerSetTitle, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Assert.Equal(newStickerSetTitle, stickerSet.Title); @@ -608,15 +653,18 @@ public async Task Should_Set_Sticker_Set_Thumbnail() ); await BotClient.SetStickerSetThumbnailAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - userId: _stickersTestsFixture.OwnerUserId, - thumbnail: new InputFileStream(stream) + new() + { + Name = classFixture.TestStaticRegularStickerSetName, + UserId = classFixture.OwnerUserId, + Thumbnail = InputFile.FromStream(stream), + } ); await Task.Delay(1_000); StickerSet updatedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName } ); Assert.NotNull(updatedStickerSet.Thumbnail); @@ -634,18 +682,21 @@ public async Task Should_Throw_InvalidStickerSetNameException() List inputStickers = [ new( - sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromFileId(classFixture.TestUploadedStaticStickerFile.FileId), + emojiList: classFixture.FirstEmojis ) ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: "Invalid_Sticker_Set_Name", - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Name = "Invalid_Sticker_Set_Name", + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + } ) ); @@ -663,18 +714,21 @@ public async Task Should_Throw_InvalidStickerEmojisException() List inputStickers = [ new( - sticker: new InputFileId(_stickersTestsFixture.TestUploadedStaticStickerFile.FileId), + sticker: InputFile.FromFileId(classFixture.TestUploadedStaticStickerFile.FileId), emojiList: invalidEmojis ) ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + } ) ); @@ -694,21 +748,24 @@ public async Task Should_Throw_InvalidStickerDimensionsException() List inputStickers = [ new( - sticker: new InputFileStream(stream, "logo.png"), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromStream(stream, "logo.png"), + emojiList: classFixture.FirstEmojis ) ]; //New name, because an exception might be thrown: Bad Request: sticker set name is already occupied - string newStickerSetName = $"new_{_stickersTestsFixture.TestStaticRegularStickerSetName}"; + string newStickerSetName = $"new_{classFixture.TestStaticRegularStickerSetName}"; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: newStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Name = newStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + } ) ); @@ -726,18 +783,21 @@ public async Task Should_Throw_InvalidFileSizeException() List inputStickers = [ new( - sticker: new InputFileStream(stream, "apes.jpg"), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromStream(stream, "apes.jpg"), + emojiList: classFixture.FirstEmojis ) ]; ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + } ) ); @@ -756,19 +816,22 @@ public async Task Should_Throw_StickerSetNameExistsException() List inputStickers = [ new( - sticker: new InputFileStream(stream, "ruby.png"), - emojiList: _stickersTestsFixture.FirstEmojis + sticker: InputFile.FromStream(stream, "ruby.png"), + emojiList: classFixture.FirstEmojis ) ]; // Telegram for some reason does not return an error, so the test is skipped ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticRegularStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticRegularStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + } ) ); @@ -782,21 +845,19 @@ public async Task Should_Throw_StickerSetNotModifiedException() { const string expectedExceptionMessage = "Bad Request: STICKERSET_NOT_MODIFIED"; - StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName - ); + StickerSet stickerSet = await BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName }); Sticker lastSticker = stickerSet.Stickers.Last(); await BotClient.DeleteStickerFromSetAsync( - sticker: new(lastSticker.FileId) + new DeleteStickerFromSetRequest { Sticker = InputFile.FromFileId(lastSticker.FileId) } ); await Task.Delay(TimeSpan.FromSeconds(10)); ApiRequestException exception = await Assert.ThrowsAsync(async () => await BotClient.DeleteStickerFromSetAsync( - sticker: new(lastSticker.FileId) + new DeleteStickerFromSetRequest { Sticker = new(lastSticker.FileId) } ) ); @@ -812,36 +873,22 @@ public async Task Should_Delete_Sticker_Sets() { const string expectedExceptionMessage = "Bad Request: STICKERSET_INVALID"; - await BotClient.DeleteStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName - ); - - await BotClient.DeleteStickerSetAsync( - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName - ); - - await BotClient.DeleteStickerSetAsync( - name: _stickersTestsFixture.TestVideoRegularStickerSetName - ); + await BotClient.DeleteStickerSetAsync(new DeleteStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName }); + await BotClient.DeleteStickerSetAsync(new DeleteStickerSetRequest { Name = classFixture.TestAnimatedRegularStickerSetName }); + await BotClient.DeleteStickerSetAsync(new DeleteStickerSetRequest { Name = classFixture.TestVideoRegularStickerSetName }); await Task.Delay(1_000); ApiRequestException staticException = await Assert.ThrowsAsync(() => - BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticRegularStickerSetName - ) + BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = classFixture.TestStaticRegularStickerSetName }) ); ApiRequestException animatedException = await Assert.ThrowsAsync(() => - BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestAnimatedRegularStickerSetName - ) + BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = classFixture.TestAnimatedRegularStickerSetName }) ); ApiRequestException videoException = await Assert.ThrowsAsync(() => - BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestVideoRegularStickerSetName - ) + BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = classFixture.TestVideoRegularStickerSetName }) ); Assert.Equal(expectedExceptionMessage, staticException.Message); @@ -862,29 +909,33 @@ public async Task Should_Create_New_Mask_Static_Sticker_Set() List inputStickers = [ new( - sticker: new InputFileStream(stream, "tux.png"), - emojiList: _stickersTestsFixture.SecondEmojis) + sticker: InputFile.FromStream(stream, "tux.png"), + emojiList: classFixture.SecondEmojis + ) ]; await BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticMaskStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static, - stickerType: StickerType.Mask + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticMaskStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + StickerType = StickerType.Mask, + } ); await Task.Delay(1_000); - _stickersTestsFixture.TestStaticMaskStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName + classFixture.TestStaticMaskStickerSet = await BotClient.GetStickerSetAsync( + new GetStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName } ); - Assert.Equal(StickerType.Mask, _stickersTestsFixture.TestStaticMaskStickerSet.StickerType); - Assert.False(_stickersTestsFixture.TestStaticMaskStickerSet.IsAnimated); - Assert.False(_stickersTestsFixture.TestStaticMaskStickerSet.IsVideo); - Assert.Single(_stickersTestsFixture.TestStaticMaskStickerSet.Stickers); + Assert.Equal(StickerType.Mask, classFixture.TestStaticMaskStickerSet.StickerType); + Assert.False(classFixture.TestStaticMaskStickerSet.IsAnimated); + Assert.False(classFixture.TestStaticMaskStickerSet.IsVideo); + Assert.Single(classFixture.TestStaticMaskStickerSet.Stickers); } [OrderedFact("Should add VLC logo sticker with mask position like hat on forehead")] @@ -895,8 +946,8 @@ public async Task Should_Add_Sticker_With_Mask_Position_To_Set() await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Vlc); InputSticker inputSticker = new( - sticker: new InputFileStream(stream, "vlc.png"), - emojiList: _stickersTestsFixture.SecondEmojis + sticker: InputFile.FromStream(stream, "vlc.png"), + emojiList: classFixture.SecondEmojis ) { MaskPosition = new() @@ -907,15 +958,18 @@ public async Task Should_Add_Sticker_With_Mask_Position_To_Set() }; await BotClient.AddStickerToSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticMaskStickerSetName, - sticker: inputSticker + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticMaskStickerSetName, + Sticker = inputSticker, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName } ); Assert.Equal(StickerType.Mask, stickerSet.StickerType); @@ -941,20 +995,23 @@ public async Task Should_Set_Mask_Position_From_Last_Sticker() }; StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName } ); Sticker sticker = stickerSet.Stickers.First(); await BotClient.SetStickerMaskPositionAsync( - sticker: new(sticker.FileId), - maskPosition: newMaskPosition + new SetStickerMaskPositionRequest + { + Sticker = InputFile.FromFileId(sticker.FileId), + MaskPosition = newMaskPosition, + } ); await Task.Delay(1_000); StickerSet changedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName } ); Sticker changedSticker = changedStickerSet.Stickers.First(); @@ -972,15 +1029,13 @@ public async Task Should_Delete_Mask_Sticker_Set() const string expectedExceptionMessage = "Bad Request: STICKERSET_INVALID"; await BotClient.DeleteStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName + new DeleteStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName } ); await Task.Delay(TimeSpan.FromSeconds(10)); ApiRequestException exception = await Assert.ThrowsAsync(() => - BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticMaskStickerSetName - ) + BotClient.GetStickerSetAsync(new GetStickerSetRequest { Name = classFixture.TestStaticMaskStickerSetName }) ); Assert.Equal(expectedExceptionMessage, exception.Message); @@ -1000,29 +1055,33 @@ public async Task Should_Create_New_Custom_Emoji_Static_Sticker_Set() List inputStickers = [ new( - sticker: new InputFileStream(stream, "Static1.png"), - emojiList: _stickersTestsFixture.FirstEmojis) + sticker: InputFile.FromStream(stream, "Static1.png"), + emojiList: classFixture.FirstEmojis + ) ]; await BotClient.CreateNewStickerSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName, - title: _stickersTestsFixture.TestStickerSetTitle, - stickers: inputStickers, - stickerFormat: StickerFormat.Static, - stickerType: StickerType.CustomEmoji + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticCustomEmojiStickerSetName, + Title = classFixture.TestStickerSetTitle, + Stickers = inputStickers, + StickerFormat = StickerFormat.Static, + StickerType = StickerType.CustomEmoji, + } ); await Task.Delay(1_000); - _stickersTestsFixture.TestStaticCustomEmojiStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + classFixture.TestStaticCustomEmojiStickerSet = await BotClient.GetStickerSetAsync( + new GetStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ); - Assert.Equal(StickerType.CustomEmoji, _stickersTestsFixture.TestStaticCustomEmojiStickerSet.StickerType); - Assert.False(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.IsAnimated); - Assert.False(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.IsVideo); - Assert.Single(_stickersTestsFixture.TestStaticCustomEmojiStickerSet.Stickers); + Assert.Equal(StickerType.CustomEmoji, classFixture.TestStaticCustomEmojiStickerSet.StickerType); + Assert.False(classFixture.TestStaticCustomEmojiStickerSet.IsAnimated); + Assert.False(classFixture.TestStaticCustomEmojiStickerSet.IsVideo); + Assert.Single(classFixture.TestStaticCustomEmojiStickerSet.Stickers); } [OrderedFact("Should add sticker to a custom emoji set")] @@ -1033,20 +1092,23 @@ public async Task Should_Add_Sticker_To_A_Custom_Emoji_set() await using System.IO.Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Sticker.CustomEmoji.StaticSecond); InputSticker inputSticker = new( - sticker: new InputFileStream(stream, "Static2.png"), - emojiList: _stickersTestsFixture.SecondEmojis + sticker: InputFile.FromStream(stream, "Static2.png"), + emojiList: classFixture.SecondEmojis ); await BotClient.AddStickerToSetAsync( - userId: _stickersTestsFixture.OwnerUserId, - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName, - sticker: inputSticker + new() + { + UserId = classFixture.OwnerUserId, + Name = classFixture.TestStaticCustomEmojiStickerSetName, + Sticker = inputSticker, + } ); await Task.Delay(1_000); StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ); Assert.Equal(StickerType.CustomEmoji, stickerSet.StickerType); @@ -1065,7 +1127,7 @@ await BotClient.AddStickerToSetAsync( public async Task Should_Set_Custom_Emoji_Set_Thumbnail() { StickerSet stickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ); Sticker lastSticker = stickerSet.Stickers.Last(); @@ -1073,12 +1135,15 @@ public async Task Should_Set_Custom_Emoji_Set_Thumbnail() Assert.NotNull(lastSticker.CustomEmojiId); await BotClient.SetCustomEmojiStickerSetThumbnailAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName, - customEmojiId: lastSticker.CustomEmojiId + new SetCustomEmojiStickerSetThumbnailRequest + { + Name = classFixture.TestStaticCustomEmojiStickerSetName, + CustomEmojiId = lastSticker.CustomEmojiId, + } ); StickerSet changedStickerSet = await BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ); Assert.NotNull(changedStickerSet.Thumbnail); @@ -1096,14 +1161,14 @@ public async Task Should_Delete_Custom_Emoji_Sticker_Set() const string expectedExceptionMessage = "Bad Request: STICKERSET_INVALID"; await BotClient.DeleteStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + new DeleteStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ); await Task.Delay(1_000); ApiRequestException exception = await Assert.ThrowsAsync(() => BotClient.GetStickerSetAsync( - name: _stickersTestsFixture.TestStaticCustomEmojiStickerSetName + new GetStickerSetRequest { Name = classFixture.TestStaticCustomEmojiStickerSetName } ) ); diff --git a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs index d2ae50cce..b7aa26a00 100644 --- a/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs +++ b/test/Telegram.Bot.Tests.Integ/Stickers/StickersTestsFixture.cs @@ -1,76 +1,68 @@ +using System; using System.Collections.Generic; using System.Threading.Tasks; using Telegram.Bot.Tests.Integ.Framework; +using Telegram.Bot.Tests.Integ.Framework.Fixtures; using Telegram.Bot.Types; using Telegram.Bot.Types.ReplyMarkups; +using Xunit; namespace Telegram.Bot.Tests.Integ.Stickers; -public class StickersTestsFixture +public class StickersTestsFixture(TestsFixture testsFixture) : AsyncLifetimeFixture { + protected override IEnumerable> Initializers() => + [ + async () => + { + OwnerUserId = await GetStickerOwnerIdAsync( + testsFixture, + Constants.TestCollections.Stickers + ); + } + ]; + //Basic information - public string TestStickerSetTitle { get; } + public string TestStickerSetTitle => "Test sticker set"; - public long OwnerUserId { get; } + public long OwnerUserId { get; private set; } //Emojis - public IEnumerable FirstEmojis { get; } + public IEnumerable FirstEmojis { get; } = ["😊"]; - public IEnumerable SecondEmojis { get; } + public IEnumerable SecondEmojis { get; } = ["🥰", "😘"]; - public IEnumerable ThirdEmojis { get; } + public IEnumerable ThirdEmojis { get; } = ["😎"]; //Regular stickers - public string TestStaticRegularStickerSetName { get; } + public string TestStaticRegularStickerSetName { get; } = $"test_static_regular_set_by_{testsFixture.BotUser.Username}"; public File TestUploadedStaticStickerFile { get; set; } public StickerSet TestStaticRegularStickerSet { get; set; } - public string TestAnimatedRegularStickerSetName { get; } + public string TestAnimatedRegularStickerSetName { get; } = $"test_animated_regular_set_by_{testsFixture.BotUser.Username}"; public File TestUploadedAnimatedStickerFile { get; set; } public StickerSet TestAnimatedRegularStickerSet { get; set; } - public string TestVideoRegularStickerSetName { get; } + public string TestVideoRegularStickerSetName { get; } = $"test_video_regular_set_by_{testsFixture.BotUser.Username}"; public File TestUploadedVideoStickerFile { get; set; } public StickerSet TestVideoRegularStickerSet { get; set; } //Mask stickers - public string TestStaticMaskStickerSetName { get; } + public string TestStaticMaskStickerSetName { get; } = $"test_static_mask_set_by_{testsFixture.BotUser.Username}"; public StickerSet TestStaticMaskStickerSet { get; set; } //Custom emoji stickers - public string TestStaticCustomEmojiStickerSetName { get; } + public string TestStaticCustomEmojiStickerSetName { get; } = $"test_static_c_emoji_set_by_{testsFixture.BotUser.Username}"; public StickerSet TestStaticCustomEmojiStickerSet { get; set; } - public StickersTestsFixture(TestsFixture testsFixture) - { - TestStickerSetTitle = "Test sticker set"; - - OwnerUserId = GetStickerOwnerIdAsync( - testsFixture, - Constants.TestCollections.Stickers - ).GetAwaiter().GetResult(); - - FirstEmojis = new string[] { "😊" }; - SecondEmojis = new string[] { "🥰", "😘" }; - ThirdEmojis = new string[] { "😎" }; - - TestStaticRegularStickerSetName = $"test_static_regular_set_by_{testsFixture.BotUser.Username}"; - TestAnimatedRegularStickerSetName = $"test_animated_regular_set_by_{testsFixture.BotUser.Username}"; - TestVideoRegularStickerSetName = $"test_video_regular_set_by_{testsFixture.BotUser.Username}"; - - TestStaticMaskStickerSetName = $"test_static_mask_set_by_{testsFixture.BotUser.Username}"; - - TestStaticCustomEmojiStickerSetName = $"test_static_c_emoji_set_by_{testsFixture.BotUser.Username}"; - } - static async Task GetStickerOwnerIdAsync(TestsFixture testsFixture, string collectionName) { long ownerId; @@ -85,14 +77,16 @@ static async Task GetStickerOwnerIdAsync(TestsFixture testsFixture, string ); const string cqData = "sticker_tests:owner"; - Message cqMessage = await testsFixture.BotClient.SendTextMessageAsync( - testsFixture.SupergroupChat, - testsFixture.UpdateReceiver.GetTesters() + - "\nUse the following button to become Sticker Set Owner", - replyParameters: new() { MessageId = notificationMessage.MessageId }, - replyMarkup: new InlineKeyboardMarkup( - InlineKeyboardButton.WithCallbackData("I am the Owner!", cqData) - ) + Message cqMessage = await testsFixture.BotClient.SendMessageAsync( + new() + { + ChatId = testsFixture.SupergroupChat, + Text = $"{testsFixture.UpdateReceiver.GetTesters()}\nUse the following button to become Sticker Set Owner", + ReplyParameters = new() { MessageId = notificationMessage.MessageId }, + ReplyMarkup = new InlineKeyboardMarkup( + InlineKeyboardButton.WithCallbackData("I am the Owner!", cqData) + ), + } ); Update cqUpdate = await testsFixture.UpdateReceiver diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs index 8c2c33775..c4ddd514e 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -10,53 +11,52 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.DeleteMessage)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class DeleteMessageTests +public class DeleteMessageTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public DeleteMessageTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should delete message generated from an inline query result")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] public async Task Should_Delete_Message_From_InlineQuery() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Starting the inline query with this message...", startInlineQuery: true ); - Update queryUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update queryUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); await BotClient.AnswerInlineQueryAsync( - inlineQueryId: queryUpdate.InlineQuery!.Id, - results: new[] - { - new InlineQueryResultArticle - { - Id = "article-to-delete", - Title = "Telegram Bot API", - InputMessageContent = new InputTextMessageContent { MessageText = "https://www.telegram.org/"}, - } - }, - cacheTime: 0 + new() + { + InlineQueryId = queryUpdate.InlineQuery!.Id, + Results = new[] + { + new InlineQueryResultArticle + { + Id = "article-to-delete", + Title = "Telegram Bot API", + InputMessageContent = new InputTextMessageContent { MessageText = "https://www.telegram.org/"}, + } + }, + CacheTime = 0, + } ); (Update messageUpdate, _) = - await _fixture.UpdateReceiver.GetInlineQueryResultUpdates( - chatId: _fixture.SupergroupChat.Id, + await fixture.UpdateReceiver.GetInlineQueryResultUpdates( + chatId: fixture.SupergroupChat.Id, messageType: MessageType.Text ); await Task.Delay(1_000); await BotClient.DeleteMessageAsync( - chatId: messageUpdate.Message!.Chat.Id, - messageId: messageUpdate.Message.MessageId + new() + { + ChatId = messageUpdate.Message!.Chat.Id, + MessageId = messageUpdate.Message.MessageId, + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs index cdbcd3588..79964fe39 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/DeleteMessageTests2.cs @@ -9,9 +9,7 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] public class DeleteMessageTests2(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture = fixture; + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should delete message")] @@ -19,16 +17,22 @@ public class DeleteMessageTests2(TestsFixture fixture) [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteMessage)] public async Task Should_Delete_Message() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "This message will be deleted shortly" + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "This message will be deleted shortly", + } ); await Task.Delay(1_000); await BotClient.DeleteMessageAsync( - chatId: message.Chat.Id, - messageId: message.MessageId + new() + { + ChatId = message.Chat.Id, + MessageId = message.MessageId, + } ); } @@ -37,14 +41,20 @@ await BotClient.DeleteMessageAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.DeleteMessages)] public async Task Should_Delete_Messages() { - Message message1 = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Message one.\nThis message will be deleted shortly" + Message message1 = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "Message one.\nThis message will be deleted shortly", + } ); - Message message2 = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Message two.\nThis message will be deleted shortly" + Message message2 = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "Message two.\nThis message will be deleted shortly", + } ); int[] messageIds = [message1.MessageId, message2.MessageId]; @@ -52,8 +62,11 @@ public async Task Should_Delete_Messages() await Task.Delay(1_000); await BotClient.DeleteMessagesAsync( - chatId: _fixture.SupergroupChat.Id, - messageIds: messageIds + new() + { + ChatId = fixture.SupergroupChat.Id, + MessageIds = messageIds, + } ); } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs index 4648b5884..787f5779f 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -13,43 +14,36 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.EditMessage)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class EditMessageContentTests +public class EditMessageContentTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public EditMessageContentTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should edit an inline message's text")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageText)] public async Task Should_Edit_Inline_Message_Text() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Starting the inline query with this message...", startInlineQuery: true ); #region Answer Inline Query with an Article - Update inlineQUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update inlineQUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); Assert.NotNull(inlineQUpdate.InlineQuery); const string originalMessagePrefix = "original\n"; (MessageEntityType Type, string Value)[] entityValueMappings = - { + [ (MessageEntityType.Bold, "bold"), - (MessageEntityType.Italic, "italic"), - }; + (MessageEntityType.Italic, "italic") + ]; string messageText = $"{originalMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; string data = $"change-text{new Random().Next(2_000)}"; InlineQueryResult[] inlineQueryResults = - { + [ new InlineQueryResultArticle { Id = "bot-api", @@ -61,13 +55,20 @@ await _fixture.SendTestInstructionsAsync( }, ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to modify text", data) } - }; + ]; - await BotClient.AnswerInlineQueryAsync(inlineQUpdate.InlineQuery.Id, inlineQueryResults, 0); + await BotClient.AnswerInlineQueryAsync( + new() + { + InlineQueryId = inlineQUpdate.InlineQuery.Id, + Results = inlineQueryResults, + CacheTime = 0, + } + ); #endregion - Update callbackQUpdate = await _fixture.UpdateReceiver + Update callbackQUpdate = await fixture.UpdateReceiver .GetCallbackQueryUpdateAsync(data: data); Assert.NotNull(callbackQUpdate.CallbackQuery); @@ -77,9 +78,12 @@ await _fixture.SendTestInstructionsAsync( messageText = $"{modifiedMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; await BotClient.EditMessageTextAsync( - inlineMessageId: callbackQUpdate.CallbackQuery.InlineMessageId, - text: messageText, - parseMode: ParseMode.Html + new EditInlineMessageTextRequest + { + InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, + Text = messageText, + ParseMode = ParseMode.Html, + } ); } @@ -88,14 +92,14 @@ await BotClient.EditMessageTextAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageReplyMarkup)] public async Task Should_Edit_Inline_Message_Markup() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Starting the inline query with this message...", startInlineQuery: true ); #region Answer Inline Query with an Article - Update inlineQUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update inlineQUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); Assert.NotNull(inlineQUpdate.InlineQuery); string data = "change-me" + new Random().Next(2_000); @@ -110,7 +114,7 @@ await _fixture.SendTestInstructionsAsync( }; InlineQueryResult[] inlineQueryResults = - { + [ new InlineQueryResultArticle { Id = "bot-api", @@ -118,22 +122,32 @@ await _fixture.SendTestInstructionsAsync( InputMessageContent = inputMessageContent, Description = "The Bot API is an HTTP-based interface created for developers", ReplyMarkup = initialMarkup, - }, - }; + } + ]; - await BotClient.AnswerInlineQueryAsync(inlineQUpdate.InlineQuery.Id, inlineQueryResults, 0); + await BotClient.AnswerInlineQueryAsync( + new() + { + InlineQueryId = inlineQUpdate.InlineQuery.Id, + Results = inlineQueryResults, + CacheTime = 0, + } + ); #endregion - Update callbackQUpdate = await _fixture.UpdateReceiver + Update callbackQUpdate = await fixture.UpdateReceiver .GetCallbackQueryUpdateAsync(data: data); Assert.NotNull(callbackQUpdate.CallbackQuery); Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); await BotClient.EditMessageReplyMarkupAsync( - inlineMessageId: callbackQUpdate.CallbackQuery.InlineMessageId, - replyMarkup: "✌ Edited 👌" + new EditInlineMessageReplyMarkupRequest + { + InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, + ReplyMarkup = "✌ Edited 👌", + } ); } @@ -142,14 +156,14 @@ await BotClient.EditMessageReplyMarkupAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageCaption)] public async Task Should_Edit_Inline_Message_Caption() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Starting the inline query with this message...", startInlineQuery: true ); #region Answer Inline Query with an Article - Update inlineQUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update inlineQUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); Assert.NotNull(inlineQUpdate.InlineQuery); string data = "change-me" + new Random().Next(2_000); @@ -160,7 +174,7 @@ await _fixture.SendTestInstructionsAsync( const string url = "https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg"; InlineQueryResult[] inlineQueryResults = - { + [ new InlineQueryResultPhoto { Id = "photo1", @@ -169,22 +183,32 @@ await _fixture.SendTestInstructionsAsync( Caption = "Message caption will be updated shortly", ReplyMarkup = replyMarkup } - }; + ]; - await BotClient.AnswerInlineQueryAsync(inlineQUpdate.InlineQuery.Id, inlineQueryResults, 0); + await BotClient.AnswerInlineQueryAsync( + new() + { + InlineQueryId = inlineQUpdate.InlineQuery.Id, + Results = inlineQueryResults, + CacheTime = 0, + } + ); #endregion - Update callbackQUpdate = await _fixture.UpdateReceiver + Update callbackQUpdate = await fixture.UpdateReceiver .GetCallbackQueryUpdateAsync(data: data); Assert.NotNull(callbackQUpdate.CallbackQuery); Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); await BotClient.EditMessageCaptionAsync( - inlineMessageId: callbackQUpdate.CallbackQuery.InlineMessageId, - caption: "_Caption is edited_ 👌", - parseMode: ParseMode.Markdown + new EditInlineMessageCaptionRequest + { + InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, + Caption = "_Caption is edited_ 👌", + ParseMode = ParseMode.Markdown, + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs index 865bbfe73..eee88e4ce 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs @@ -1,6 +1,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -11,16 +12,9 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.EditMessage2)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class EditMessageContentTests2 +public class EditMessageContentTests2(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public EditMessageContentTests2(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should edit a message's text")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendMessage)] @@ -29,16 +23,19 @@ public async Task Should_Edit_Message_Text() { const string originalMessagePrefix = "original\n"; (MessageEntityType Type, string Value)[] entityValueMappings = - { + [ (MessageEntityType.Bold, "bold"), - (MessageEntityType.Italic, "italic"), - }; + (MessageEntityType.Italic, "italic") + ]; string messageText = $"{originalMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; - Message originalMessage = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: messageText, - parseMode: ParseMode.Html + Message originalMessage = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = messageText, + ParseMode = ParseMode.Html, + } ); await Task.Delay(1_000); @@ -47,10 +44,13 @@ public async Task Should_Edit_Message_Text() messageText = $"{modifiedMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; Message editedMessage = await BotClient.EditMessageTextAsync( - chatId: originalMessage.Chat.Id, - messageId: originalMessage.MessageId, - text: messageText, - parseMode: ParseMode.Html + new EditMessageTextRequest + { + ChatId = originalMessage.Chat.Id, + MessageId = originalMessage.MessageId, + Text = messageText, + ParseMode = ParseMode.Html, + } ); Assert.NotNull(editedMessage.Text); @@ -71,18 +71,24 @@ public async Task Should_Edit_Message_Text() [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageReplyMarkup)] public async Task Should_Edit_Message_Markup() { - Message message = await BotClient.SendTextMessageAsync( - chatId: _fixture.SupergroupChat.Id, - text: "Inline keyboard will be updated shortly", - replyMarkup: (InlineKeyboardMarkup)"Original markup" + Message message = await BotClient.SendMessageAsync( + new() + { + ChatId = fixture.SupergroupChat.Id, + Text = "Inline keyboard will be updated shortly", + ReplyMarkup = (InlineKeyboardMarkup)"Original markup", + } ); await Task.Delay(1_000); Message editedMessage = await BotClient.EditMessageReplyMarkupAsync( - chatId: message.Chat.Id, - messageId: message.MessageId, - replyMarkup: "Edited 👍" + new EditMessageReplyMarkupRequest + { + ChatId = message.Chat.Id, + MessageId = message.MessageId, + ReplyMarkup = "Edited 👍", + } ); Assert.Equal(message.MessageId, editedMessage.MessageId); @@ -100,9 +106,12 @@ public async Task Should_Edit_Message_Caption() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Bot)) { originalMessage = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat.Id, - photo: new InputFileStream(stream), - caption: "Message caption will be updated shortly" + new() + { + ChatId = fixture.SupergroupChat.Id, + Photo = InputFile.FromStream(stream), + Caption = "Message caption will be updated shortly", + } ); } @@ -113,10 +122,13 @@ public async Task Should_Edit_Message_Caption() string caption = $"{captionPrefix} {captionEntity.Value}"; Message editedMessage = await BotClient.EditMessageCaptionAsync( - chatId: originalMessage.Chat.Id, - messageId: originalMessage.MessageId, - caption: caption, - parseMode: ParseMode.Markdown + new EditMessageCaptionRequest + { + ChatId = originalMessage.Chat.Id, + MessageId = originalMessage.MessageId, + Caption = caption, + ParseMode = ParseMode.Markdown, + } ); Assert.Equal(originalMessage.MessageId, editedMessage.MessageId); diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs index b14aa2582..19b770edd 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs @@ -1,5 +1,6 @@ using System.IO; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -12,34 +13,27 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.EditMessageMedia)] [Trait(Constants.CategoryTraitName, Constants.InteractiveCategoryValue)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class EditMessageMediaTests +public class EditMessageMediaTests(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public EditMessageMediaTests(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should change an inline message's photo to an audio using URL")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.AnswerInlineQuery)] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.EditMessageMedia)] public async Task Should_Edit_Inline_Message_Photo() { - await _fixture.SendTestInstructionsAsync( + await fixture.SendTestInstructionsAsync( "Starting the inline query with this message...", startInlineQuery: true ); #region Answer Inline Query with a media message - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); Assert.NotNull(iqUpdate.InlineQuery); InlineQueryResult[] inlineQueryResults = - { + [ new InlineQueryResultPhoto { Id = "photo:rainbow-girl", @@ -48,14 +42,21 @@ await _fixture.SendTestInstructionsAsync( Caption = "Rainbow Girl", ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to edit"), } - }; + ]; - await BotClient.AnswerInlineQueryAsync(iqUpdate.InlineQuery.Id, inlineQueryResults, 0); + await BotClient.AnswerInlineQueryAsync( + new() + { + InlineQueryId = iqUpdate.InlineQuery.Id, + Results = inlineQueryResults, + CacheTime = 0, + } + ); #endregion // Bot waits for user to click on inline button under the media - Update cqUpdate = await _fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(data: "Click here to edit"); + Update cqUpdate = await fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(data: "Click here to edit"); Assert.NotNull(cqUpdate.CallbackQuery); Assert.NotNull(cqUpdate.CallbackQuery.InlineMessageId); @@ -64,12 +65,15 @@ await _fixture.SendTestInstructionsAsync( // either an URL or the file_id of a previously uploaded media. InputFileUrl inputFileUrl = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3"); await BotClient.EditMessageMediaAsync( - inlineMessageId: cqUpdate.CallbackQuery.InlineMessageId, - media: new InputMediaAudio + new EditInlineMessageMediaRequest { - Media = inputFileUrl, - Caption = "**Audio** in `.mp3` format", - ParseMode = ParseMode.Markdown, + InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, + Media = new InputMediaAudio + { + Media = inputFileUrl, + Caption = "**Audio** in `.mp3` format", + ParseMode = ParseMode.Markdown, + }, } ); } @@ -83,12 +87,15 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() // Upload a GIF file to Telegram servers and obtain its file_id. This file_id will be used later in test. await using Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Animation.Earth); Message gifMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileStream(stream, "Earth.gif"), - caption: "`file_id` of this GIF will be used", - parseMode: ParseMode.Markdown, - replyMarkup: (InlineKeyboardMarkup) InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start Inline Query") + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromStream(stream, "Earth.gif"), + Caption = "`file_id` of this GIF will be used", + ParseMode = ParseMode.Markdown, + ReplyMarkup = (InlineKeyboardMarkup) InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start Inline Query"), + } ); Assert.NotNull(gifMessage.Document); @@ -96,11 +103,11 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() #region Answer Inline Query with a media message - Update iqUpdate = await _fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); + Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); Assert.NotNull(iqUpdate.InlineQuery); InlineQueryResult[] inlineQueryResults = - { + [ new InlineQueryResultDocument { Id = "document:acrobat", @@ -109,14 +116,21 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() MimeType = "application/pdf", ReplyMarkup = InlineKeyboardButton.WithCallbackData("Click here to edit"), } - }; + ]; - await BotClient.AnswerInlineQueryAsync(iqUpdate.InlineQuery.Id, inlineQueryResults, 0); + await BotClient.AnswerInlineQueryAsync( + new() + { + InlineQueryId = iqUpdate.InlineQuery.Id, + Results = inlineQueryResults, + CacheTime = 0, + } + ); #endregion // Bot waits for user to click on inline button under the media - Update cqUpdate = await _fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(data: "Click here to edit"); + Update cqUpdate = await fixture.UpdateReceiver.GetCallbackQueryUpdateAsync(data: "Click here to edit"); Assert.NotNull(cqUpdate.CallbackQuery); Assert.NotNull(cqUpdate.CallbackQuery.InlineMessageId); @@ -124,8 +138,11 @@ public async Task Should_Edit_Inline_Message_Document_With_FileId() // should be either an URL or the file_id of a previously uploaded media. // Also, animation thumbnail cannot be uploaded for an inline message. await BotClient.EditMessageMediaAsync( - inlineMessageId: cqUpdate.CallbackQuery.InlineMessageId, - media: new InputMediaAnimation { Media = InputFile.FromFileId(animationFileId) } + new EditInlineMessageMediaRequest + { + InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, + Media = new InputMediaAnimation { Media = InputFile.FromFileId(animationFileId) }, + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs index 786bad267..c42bd1dcb 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -10,16 +11,9 @@ namespace Telegram.Bot.Tests.Integ.Update_Messages; [Collection(Constants.TestCollections.EditMessageMedia2)] [TestCaseOrderer(Constants.TestCaseOrderer, Constants.AssemblyName)] -public class EditMessageMediaTests2 +public class EditMessageMediaTests2(TestsFixture fixture) { - ITelegramBotClient BotClient => _fixture.BotClient; - - readonly TestsFixture _fixture; - - public EditMessageMediaTests2(TestsFixture fixture) - { - _fixture = fixture; - } + ITelegramBotClient BotClient => fixture.BotClient; [OrderedFact("Should change a message's video to a document file")] [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendVideo)] @@ -31,9 +25,12 @@ public async Task Should_Edit_Message_Video() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Animation.Earth)) { originalMessage = await BotClient.SendVideoAsync( - chatId: _fixture.SupergroupChat, - video: new InputFileStream(stream), - caption: "This message will be edited shortly" + new() + { + ChatId = fixture.SupergroupChat, + Video = InputFile.FromStream(stream), + Caption = "This message will be edited shortly", + } ); } @@ -44,13 +41,16 @@ public async Task Should_Edit_Message_Video() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Certificate.PublicKey)) { editedMessage = await BotClient.EditMessageMediaAsync( - chatId: originalMessage.Chat, - messageId: originalMessage.MessageId, - media: new InputMediaDocument + new EditMessageMediaRequest { - Media = InputFile.FromStream(stream, "public-key.pem.txt"), - Caption = "**Public** key in `.pem` format", - ParseMode = ParseMode.Markdown, + ChatId = originalMessage.Chat, + MessageId = originalMessage.MessageId, + Media = new InputMediaDocument + { + Media = InputFile.FromStream(stream, "public-key.pem.txt"), + Caption = "**Public** key in `.pem` format", + ParseMode = ParseMode.Markdown, + }, } ); } @@ -70,18 +70,24 @@ public async Task Should_Edit_Message_Photo() { // Upload a GIF file to Telegram servers and obtain its file_id. This file_id will be used later in test. Message gifMessage = await BotClient.SendDocumentAsync( - chatId: _fixture.SupergroupChat, - document: new InputFileUrl(new Uri("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif")), - caption: "`file_id` of this GIF will be used" + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromUri(new Uri("https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif")), + Caption = "`file_id` of this GIF will be used", + } ); Assert.NotNull(gifMessage.Document); // Send a photo to chat. This media will be changed later in test. Message originalMessage = await BotClient.SendPhotoAsync( - chatId: _fixture.SupergroupChat, - photo: new InputFileUrl(new Uri("https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg")), - caption: "This message will be edited shortly" + new() + { + ChatId = fixture.SupergroupChat, + Photo = InputFile.FromUri(new Uri("https://cdn.pixabay.com/photo/2017/08/30/12/45/girl-2696947_640.jpg")), + Caption = "This message will be edited shortly", + } ); await Task.Delay(500); @@ -89,15 +95,18 @@ public async Task Should_Edit_Message_Photo() // Replace audio with another audio by uploading the new file. A thumbnail image is also uploaded. await using Stream thumbStream = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); Message editedMessage = await BotClient.EditMessageMediaAsync( - chatId: originalMessage.Chat, - messageId: originalMessage.MessageId, - media: new InputMediaAnimation + new EditMessageMediaRequest { - Media = InputFile.FromFileId(gifMessage.Document.FileId), - Thumbnail = new InputFileStream(thumbStream, "thumb.jpg"), - Duration = 4, - Height = 320, - Width = 320, + ChatId = originalMessage.Chat, + MessageId = originalMessage.MessageId, + Media = new InputMediaAnimation + { + Media = InputFile.FromFileId(gifMessage.Document.FileId), + Thumbnail = InputFile.FromStream(thumbStream, "thumb.jpg"), + Duration = 4, + Height = 320, + Width = 320, + } } ); From 2c2404236e4b2d82746215817ef0970c3a4c9b30 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 03:47:28 +0400 Subject: [PATCH 82/90] Add the word inline for method for the inline mode --- ...mBotClientExtensions.ApiMethods.Requests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs index a53fd831a..0ecc34fae 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.Requests.cs @@ -1196,14 +1196,14 @@ await botClient.ThrowIfNull() /// /// Use this method to edit live location messages. A location can be edited until its /// expires or editing is explicitly disabled by a call to - /// . + /// . /// /// An instance of /// Request parameters /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task EditMessageLiveLocationAsync( + public static async Task EditInlineMessageLiveLocationAsync( this ITelegramBotClient botClient, EditInlineMessageLiveLocationRequest request, CancellationToken cancellationToken = default @@ -1278,7 +1278,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task StopMessageLiveLocationAsync( + public static async Task StopInlineMessageLiveLocationAsync( this ITelegramBotClient botClient, StopInlineMessageLiveLocationRequest request, CancellationToken cancellationToken = default @@ -1715,7 +1715,7 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// On success, returns an Array of objects. - public static async Task GetGameHighScoresAsync( + public static async Task GetInlineGameHighScoresAsync( this ITelegramBotClient botClient, GetInlineGameHighScoresRequest request, CancellationToken cancellationToken = default @@ -1775,7 +1775,7 @@ await botClient.ThrowIfNull() /// Returns an error, if the new score is not greater than the user's current score in the chat and /// is /// - public static async Task SetGameScoreAsync( + public static async Task SetInlineGameScoreAsync( this ITelegramBotClient botClient, SetInlineGameScoreRequest request, CancellationToken cancellationToken = default @@ -2371,7 +2371,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task EditMessageCaptionAsync( + public static async Task EditInlineMessageCaptionAsync( this ITelegramBotClient botClient, EditInlineMessageCaptionRequest request, CancellationToken cancellationToken = default @@ -2391,7 +2391,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task EditMessageMediaAsync( + public static async Task EditInlineMessageMediaAsync( this ITelegramBotClient botClient, EditInlineMessageMediaRequest request, CancellationToken cancellationToken = default @@ -2408,7 +2408,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task EditMessageReplyMarkupAsync( + public static async Task EditInlineMessageReplyMarkupAsync( this ITelegramBotClient botClient, EditInlineMessageReplyMarkupRequest request, CancellationToken cancellationToken = default @@ -2425,7 +2425,7 @@ await botClient.ThrowIfNull() /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// - public static async Task EditMessageTextAsync( + public static async Task EditInlineMessageTextAsync( this ITelegramBotClient botClient, EditInlineMessageTextRequest request, CancellationToken cancellationToken = default From 587346459ada0ab5138af1f9dc740cbd2ab77f30 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 03:48:00 +0400 Subject: [PATCH 83/90] Migrate the rest of integration tests to use the new APIs with request classes --- .../Games/GamesTests.cs | 4 +- .../Inline Mode/InlineQueryTests.cs | 131 ++++++++++++------ .../InlineMessageLiveLocationTests .cs | 4 +- .../Other/BotDescriptionTests.cs | 48 +++++-- .../Other/ChatInfoTests.cs | 39 ++++-- .../Other/DiceTests.cs | 23 ++- .../Other/FileDownloadTests.cs | 12 +- .../Other/GetUserProfileTests.cs | 6 +- .../Other/LeaveChatTests.cs | 8 +- .../EditMessageContentTests.cs | 6 +- .../Update Messages/EditMessageMediaTests.cs | 4 +- 11 files changed, 194 insertions(+), 91 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs index 71f23783f..6c9ca7b09 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs @@ -63,7 +63,7 @@ await fixture.UpdateReceiver.GetInlineQueryResultUpdates( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetGameHighScores)] public async Task Should_Get_High_Scores_Inline_Message() { - GameHighScore[] highScores = await BotClient.GetGameHighScoresAsync( + GameHighScore[] highScores = await BotClient.GetInlineGameHighScoresAsync( new GetInlineGameHighScoresRequest { UserId = classFixture.Player.Id, @@ -90,7 +90,7 @@ await fixture.SendTestInstructionsAsync( $"Changing score from {oldScore} to {newScore} for {classFixture.Player.Username!.Replace("_", @"\_")}." ); - await BotClient.SetGameScoreAsync( + await BotClient.SetInlineGameScoreAsync( new SetInlineGameScoreRequest { UserId = playerId, diff --git a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs index 10e492213..103922f75 100644 --- a/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Inline Mode/InlineQueryTests.cs @@ -277,9 +277,12 @@ await fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -303,10 +306,13 @@ public async Task Should_Answer_Inline_Query_With_Cached_Photo() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Photos.Apes)) { photoMessage = await BotClient.SendPhotoAsync( - chatId: fixture.SupergroupChat, - photo: InputFile.FromStream(stream), - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query") + new() + { + ChatId = fixture.SupergroupChat, + Photo = InputFile.FromStream(stream), + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } ); } @@ -325,9 +331,12 @@ public async Task Should_Answer_Inline_Query_With_Cached_Photo() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -369,9 +378,12 @@ await fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -418,9 +430,12 @@ await fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -441,10 +456,13 @@ public async Task Should_Answer_Inline_Query_With_Cached_Video() { // Video from https://pixabay.com/en/videos/fireworks-rocket-new-year-s-eve-7122/ Message videoMessage = await BotClient.SendVideoAsync( - chatId: fixture.SupergroupChat, - video: InputFile.FromUri("https://pixabay.com/en/videos/download/video-7122_medium.mp4"), - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query") + new() + { + ChatId = fixture.SupergroupChat, + Video = InputFile.FromUri("https://pixabay.com/en/videos/download/video-7122_medium.mp4"), + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } ); Update iqUpdate = await fixture.UpdateReceiver.GetInlineQueryUpdateAsync(); @@ -462,9 +480,12 @@ public async Task Should_Answer_Inline_Query_With_Cached_Video() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -504,9 +525,12 @@ await fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -530,12 +554,15 @@ public async Task Should_Answer_Inline_Query_With_Cached_Audio() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.CantinaRagMp3)) { audioMessage = await BotClient.SendAudioAsync( - chatId: fixture.SupergroupChat, - audio: InputFile.FromStream(stream), - performer: "Jackson F. Smith", - duration: 201, - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query") + new() + { + ChatId = fixture.SupergroupChat, + Audio = InputFile.FromStream(stream), + Performer = "Jackson F. Smith", + Duration = 201, + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } ); } @@ -553,9 +580,12 @@ public async Task Should_Answer_Inline_Query_With_Cached_Audio() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -595,9 +625,12 @@ await fixture.SendTestInstructionsAsync( ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = @@ -620,11 +653,14 @@ public async Task Should_Answer_Inline_Query_With_Cached_Voice() await using (FileStream stream = System.IO.File.OpenRead(Constants.PathToFile.Audio.TestOgg)) { voiceMessage = await BotClient.SendVoiceAsync( - chatId: fixture.SupergroupChat, - voice: InputFile.FromStream(stream), - duration: 24, - replyMarkup: (InlineKeyboardMarkup)InlineKeyboardButton - .WithSwitchInlineQueryCurrentChat("Start inline query") + new() + { + ChatId = fixture.SupergroupChat, + Voice = InputFile.FromStream(stream), + Duration = 24, + ReplyMarkup = (InlineKeyboardMarkup)InlineKeyboardButton + .WithSwitchInlineQueryCurrentChat("Start inline query"), + } ); } @@ -642,9 +678,12 @@ public async Task Should_Answer_Inline_Query_With_Cached_Voice() ]; await BotClient.AnswerInlineQueryAsync( - inlineQueryId: iqUpdate.InlineQuery!.Id, - results: results, - cacheTime: 0 + new() + { + InlineQueryId = iqUpdate.InlineQuery!.Id, + Results = results, + CacheTime = 0, + } ); (Update messageUpdate, Update chosenResultUpdate) = diff --git a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs index c5ab0b6cf..eed141fa5 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs +++ b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs @@ -65,7 +65,7 @@ public async Task Should_Edit_Inline_Message_Live_Location() Location beijing = new() { Latitude = 39.9042f, Longitude = 116.4074f }; - await BotClient.EditMessageLiveLocationAsync( + await BotClient.EditInlineMessageLiveLocationAsync( new EditInlineMessageLiveLocationRequest { InlineMessageId = cqUpdate.CallbackQuery!.InlineMessageId!, @@ -82,7 +82,7 @@ await BotClient.EditMessageLiveLocationAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.StopMessageLiveLocation)] public async Task Should_Stop_Inline_Message_Live_Location() { - await BotClient.StopMessageLiveLocationAsync( + await BotClient.StopInlineMessageLiveLocationAsync( new StopInlineMessageLiveLocationRequest { InlineMessageId = classFixture.InlineMessageId, diff --git a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs index 9c1ef8926..570dcaa04 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/BotDescriptionTests.cs @@ -22,7 +22,10 @@ public async Task Should_Set_New_Bot_Description() string description = "Test bot description"; await BotClient.SetMyDescriptionAsync( - description: description + new SetMyDescriptionRequest + { + Description = description, + } ); } @@ -30,10 +33,13 @@ await BotClient.SetMyDescriptionAsync( [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.GetMyDescription)] public async Task Should_Get_Set_Bot_Description() { - string description = "Test bot description"; + const string description = "Test bot description"; await BotClient.SetMyDescriptionAsync( - description: description + new SetMyDescriptionRequest + { + Description = description, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); @@ -51,7 +57,10 @@ public async Task Should_Delete_Bot_Description() string description = "Test bot description"; await BotClient.SetMyDescriptionAsync( - description: description + new SetMyDescriptionRequest + { + Description = description, + } ); BotDescription setDescription = await fixture.BotClient.GetMyDescriptionAsync(new GetMyDescriptionRequest()); @@ -60,7 +69,10 @@ await BotClient.SetMyDescriptionAsync( Assert.Equal(description, setDescription.Description); await BotClient.SetMyDescriptionAsync( - description: "" + new SetMyDescriptionRequest + { + Description = string.Empty, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); @@ -80,13 +92,21 @@ public async Task Should_Set_Description_With_Language_Code_Area() _languageCode = "ru"; await BotClient.SetMyDescriptionAsync( - description: description, - languageCode: _languageCode + new SetMyDescriptionRequest + { + Description = description, + LanguageCode = _languageCode, + } ); await Task.Delay(TimeSpan.FromSeconds(10)); - BotDescription newDescription = await fixture.BotClient.GetMyDescriptionAsync(languageCode: _languageCode); + BotDescription newDescription = await fixture.BotClient.GetMyDescriptionAsync( + new GetMyDescriptionRequest + { + LanguageCode = _languageCode + } + ); Assert.NotNull(newDescription); Assert.Equal(description, newDescription.Description); @@ -97,12 +117,18 @@ await BotClient.SetMyDescriptionAsync( public async Task DisposeAsync() { await BotClient.SetMyDescriptionAsync( - description: "" + new SetMyDescriptionRequest + { + Description = string.Empty, + } ); await BotClient.SetMyDescriptionAsync( - description: "", - languageCode: _languageCode + new SetMyDescriptionRequest + { + Description = string.Empty, + LanguageCode = _languageCode, + } ); } } diff --git a/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs b/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs index eb5a6710c..4172db049 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/ChatInfoTests.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Telegram.Bot.Types.Enums; @@ -21,7 +22,10 @@ public async Task Should_Get_Supergroup_Chat() Chat supergroupChat = fixture.SupergroupChat; Chat chat = await BotClient.GetChatAsync( - chatId: supergroupChat.Id + new GetChatRequest + { + ChatId = supergroupChat.Id, + } ); Assert.Equal(ChatType.Supergroup, chat.Type); @@ -45,8 +49,11 @@ public async Task Should_Get_Supergroup_Chat() public async Task Should_Get_Bot_Chat_Member() { ChatMember memberBot = await BotClient.GetChatMemberAsync( - chatId: fixture.SupergroupChat.Id, - userId: fixture.BotUser.Id + new() + { + ChatId = fixture.SupergroupChat.Id, + UserId = fixture.BotUser.Id, + } ); Assert.Equal(ChatMemberStatus.Administrator, memberBot.Status); @@ -71,13 +78,16 @@ public async Task Should_Get_Bot_Chat_Member() public async Task Should_Get_Chat_Admins() { ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync( - chatId: fixture.SupergroupChat.Id + new GetChatAdministratorsRequest + { + ChatId = fixture.SupergroupChat.Id, + } ); - ChatMember memberCreator = Assert.Single(chatAdmins, _ => _.Status == ChatMemberStatus.Creator); + ChatMember memberCreator = Assert.Single(chatAdmins, admin => admin.Status == ChatMemberStatus.Creator); Assert.IsType(memberCreator); - ChatMember memberBot = Assert.Single(chatAdmins, _ => _.User.IsBot); + ChatMember memberBot = Assert.Single(chatAdmins, admin => admin.User.IsBot); Debug.Assert(memberBot != null); Assert.True(2 <= chatAdmins.Length); // at least, Bot and the Creator @@ -94,14 +104,16 @@ public async Task Should_Get_Private_Chat() /* In order to have a private chat id, take the Creator of supergroup and use his User ID because * for a regular user, "User ID" is the same number as "Private Chat ID". */ - ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync(fixture.SupergroupChat); + ChatMember[] chatAdmins = await BotClient.GetChatAdministratorsAsync( + new GetChatAdministratorsRequest { ChatId = fixture.SupergroupChat } + ); privateChatId = chatAdmins .Single(member => member.Status == ChatMemberStatus.Creator) .User.Id; } Chat chat = await BotClient.GetChatAsync( - chatId: privateChatId + new GetChatRequest { ChatId = privateChatId, } ); Assert.Equal(ChatType.Private, chat.Type); @@ -127,7 +139,7 @@ public async Task Should_Get_Private_Chat() public async Task Should_Get_Chat_Members_Count() { int membersCount = await BotClient.GetChatMemberCountAsync( - chatId: fixture.SupergroupChat.Id + new GetChatMemberCountRequest {ChatId = fixture.SupergroupChat.Id} ); Assert.True(2 <= membersCount); // at least, Bot and the Creator @@ -142,10 +154,13 @@ public async Task Should_Get_Chat_Members_Count() public async Task Should_Send_Chat_Action() { await BotClient.SendChatActionAsync( - chatId: fixture.SupergroupChat.Id, - chatAction: ChatAction.RecordVoice + new() + { + ChatId = fixture.SupergroupChat.Id, + Action = ChatAction.RecordVoice, + } ); await Task.Delay(5_000); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs b/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs index 9d7e64190..63022311c 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/DiceTests.cs @@ -15,7 +15,12 @@ public class DiceTests(TestsFixture testsFixture) [Trait(Constants.MethodTraitName, Constants.TelegramBotApiMethods.SendDice)] public async Task Should_Send_A_Die() { - Message message = await testsFixture.BotClient.SendDiceAsync(testsFixture.SupergroupChat); + Message message = await testsFixture.BotClient.SendDiceAsync( + new SendDiceRequest + { + ChatId = testsFixture.SupergroupChat + } + ); Assert.Equal(MessageType.Dice, message.Type); Assert.NotNull(message.Dice); @@ -28,8 +33,11 @@ public async Task Should_Send_A_Die() public async Task Should_Send_A_Dart() { Message message = await testsFixture.BotClient.SendDiceAsync( - testsFixture.SupergroupChat, - emoji: Emoji.Darts + new SendDiceRequest + { + ChatId = testsFixture.SupergroupChat, + Emoji = Emoji.Darts, + } ); Assert.Equal(MessageType.Dice, message.Type); @@ -43,8 +51,11 @@ public async Task Should_Send_A_Dart() public async Task Should_Send_A_Basketball() { Message message = await testsFixture.BotClient.SendDiceAsync( - testsFixture.SupergroupChat, - emoji: Emoji.Basketball + new SendDiceRequest + { + ChatId = testsFixture.SupergroupChat, + Emoji = Emoji.Basketball, + } ); Assert.Equal(MessageType.Dice, message.Type); @@ -93,7 +104,7 @@ public async Task Should_Send_A_SlotMachine() public async Task Should_Send_A_Bowling() { Message message = await testsFixture.BotClient.SendDiceAsync( - new SendDiceRequest() + new SendDiceRequest { ChatId = testsFixture.SupergroupChat, Emoji = Emoji.Bowling diff --git a/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs b/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs index 157eb0ebe..29e533c60 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/FileDownloadTests.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Newtonsoft.Json.Linq; using Telegram.Bot.Exceptions; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -30,8 +31,11 @@ public async Task Should_Get_File_Info() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Documents.Hamlet)) { documentMessage = await BotClient.SendDocumentAsync( - chatId: fixture.SupergroupChat, - document: InputFile.FromStream(stream) + new() + { + ChatId = fixture.SupergroupChat, + Document = InputFile.FromStream(stream), + } ); } @@ -39,7 +43,7 @@ public async Task Should_Get_File_Info() #endregion - File file = await BotClient.GetFileAsync(documentMessage.Document.FileId); + File file = await BotClient.GetFileAsync(new GetFileRequest { FileId = documentMessage.Document.FileId }); Assert.Equal(fileId, file.FileId); Assert.NotNull(file.FileSize); @@ -94,7 +98,7 @@ public async Task Should_Download_Write_Using_FileId() public async Task Should_Throw_FileId_InvalidParameterException() { ApiRequestException exception = await Assert.ThrowsAsync(async () => - await BotClient.GetFileAsync("Invalid_File_id") + await BotClient.GetFileAsync(new GetFileRequest { FileId = "Invalid_File_id" }) ); Assert.Contains("file_id", exception.Message); diff --git a/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs b/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs index 26f9f0daf..2a1ae4669 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/GetUserProfileTests.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Telegram.Bot.Types; using Xunit; @@ -17,7 +18,10 @@ public class GetUserProfileTests(TestsFixture fixture) public async Task Should_Get_User_Profile_Photos() { UserProfilePhotos profilePhotos = await BotClient.GetUserProfilePhotosAsync( - userId: fixture.BotUser.Id + new GetUserProfilePhotosRequest + { + UserId = fixture.BotUser.Id, + } ); Assert.True(1 <= profilePhotos.TotalCount); diff --git a/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs b/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs index 743112c87..f1577ec19 100644 --- a/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Other/LeaveChatTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Telegram.Bot.Requests; using Telegram.Bot.Tests.Integ.Framework; using Xunit; @@ -17,7 +18,10 @@ public async Task Should_Get_Private_Chat() { // ToDo: Exception when leaving private chat await BotClient.LeaveChatAsync( - chatId: fixture.SupergroupChat + new LeaveChatRequest + { + ChatId = fixture.SupergroupChat, + } ); } -} \ No newline at end of file +} diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs index 787f5779f..25b50e781 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs @@ -77,7 +77,7 @@ await BotClient.AnswerInlineQueryAsync( const string modifiedMessagePrefix = "✌ modified 👌\n"; messageText = $"{modifiedMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; - await BotClient.EditMessageTextAsync( + await BotClient.EditInlineMessageTextAsync( new EditInlineMessageTextRequest { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, @@ -142,7 +142,7 @@ await BotClient.AnswerInlineQueryAsync( Assert.NotNull(callbackQUpdate.CallbackQuery); Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); - await BotClient.EditMessageReplyMarkupAsync( + await BotClient.EditInlineMessageReplyMarkupAsync( new EditInlineMessageReplyMarkupRequest { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, @@ -202,7 +202,7 @@ await BotClient.AnswerInlineQueryAsync( Assert.NotNull(callbackQUpdate.CallbackQuery); Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); - await BotClient.EditMessageCaptionAsync( + await BotClient.EditInlineMessageCaptionAsync( new EditInlineMessageCaptionRequest { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs index 19b770edd..235f73656 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs @@ -64,7 +64,7 @@ await BotClient.AnswerInlineQueryAsync( // Change the photo for an audio. Note that, in the case of an inline message, the new media should be // either an URL or the file_id of a previously uploaded media. InputFileUrl inputFileUrl = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3"); - await BotClient.EditMessageMediaAsync( + await BotClient.EditInlineMessageMediaAsync( new EditInlineMessageMediaRequest { InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, @@ -137,7 +137,7 @@ await BotClient.AnswerInlineQueryAsync( // Change the YouTube video for an animation. Note that, in the case of an inline message, the new media // should be either an URL or the file_id of a previously uploaded media. // Also, animation thumbnail cannot be uploaded for an inline message. - await BotClient.EditMessageMediaAsync( + await BotClient.EditInlineMessageMediaAsync( new EditInlineMessageMediaRequest { InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, From 4371fb389f7bebffd4692a78d599682b267aaed7 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 04:06:56 +0400 Subject: [PATCH 84/90] Fix XML documentation --- .../TelegramBotClientExtensions.ApiMethods.cs | 73 ++++++++++++------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs index 2df55f61d..84a09f1c2 100644 --- a/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs +++ b/src/Telegram.Bot/TelegramBotClientExtensions.ApiMethods.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using System.IO; using System.Threading; using System.Threading.Tasks; using Telegram.Bot.Extensions; @@ -27,8 +26,9 @@ public static partial class TelegramBotClientExtensions /// /// Identifier of the first update to be returned. Must be greater by one than the highest among the /// identifiers of previously received updates. By default, updates starting with the earliest unconfirmed - /// update are returned. An update is considered confirmed as soon as is called - /// with an higher than its . The negative offset can be + /// update are returned. An update is considered confirmed as soon as + /// is called with an + /// higher than its . The negative offset can be /// specified to retrieve updates starting from -offset update from the end /// of the updates queue. All previous updates will forgotten. /// @@ -119,7 +119,8 @@ await botClient.ThrowIfNull() /// /// /// Please note that this parameter doesn't affect updates created before the call to the - /// , so unwanted updates may be received for a short period of time. + /// , + /// so unwanted updates may be received for a short period of time. /// /// /// Pass to drop all pending updates @@ -134,8 +135,9 @@ await botClient.ThrowIfNull() /// /// /// - /// You will not be able to receive updates using for as long as an outgoing - /// webhook is set up + /// You will not be able to receive updates using + /// for as long as + /// an outgoing webhook is set up /// /// /// To use a self-signed certificate, you need to upload your @@ -178,7 +180,8 @@ await botClient.ThrowIfNull() /// - /// Use this method to remove webhook integration if you decide to switch back to + /// Use this method to remove webhook integration if you decide to switch back to + /// /// /// An instance of /// Pass to drop all pending updates @@ -207,7 +210,8 @@ await botClient.ThrowIfNull() /// A cancellation token that can be used by other objects or threads to receive notice of cancellation /// /// - /// On success, returns a object. If the bot is using , + /// On success, returns a object. If the bot is using + /// , /// will return an object with the field empty. /// [Obsolete("Use the overload that accepts the corresponding request class")] @@ -457,8 +461,9 @@ await botClient.ThrowIfNull() /// /// Use this method to copy messages of any kind. Service messages and invoice messages can't be copied. - /// The method is analogous to the method , but the copied message doesn't - /// have a link to the original message. + /// The method is analogous to the method + /// , + /// but the copied message doesn't have a link to the original message. /// /// An instance of /// @@ -542,8 +547,9 @@ await botClient.ThrowIfNull() /// they are skipped. Service messages, giveaway messages, giveaway winners messages, and invoice messages /// can't be copied. A quiz can be copied only if the value of the field /// CorrectOptionId is known to the bot. The method is analogous - /// to the method , but the copied messages don't have a link - /// to the original message. Album grouping is kept for copied messages. + /// to the method + /// , but the + /// copied messages don't have a link to the original message. Album grouping is kept for copied messages. /// /// An instance of /// @@ -1886,7 +1892,8 @@ await botClient.ThrowIfNull() /// /// The ImageBot needs some time to process a request and upload the /// image. Instead of sending a text message along the lines of “Retrieving image, please wait…”, the bot may - /// use with = . + /// use with + /// = . /// The user will see a “sending photo” status for the bot. /// /// @@ -1902,14 +1909,18 @@ await botClient.ThrowIfNull() /// /// Type of action to broadcast. Choose one, depending on what the user is about to receive: /// for text messages, - /// for photos, + /// for + /// photos, /// or for - /// videos, or - /// for voice notes, - /// for general files, - /// for location data, + /// videos, + /// or for + /// voice notes, + /// for + /// general files, + /// for + /// location data, /// or for - /// video notes + /// video notes /// /// Unique identifier for the target message thread; supergroups only /// @@ -2020,7 +2031,8 @@ await botClient.ThrowIfNull() /// download files of up to 20MB in size. The file can then be downloaded via the link /// https://api.telegram.org/file/bot<token>/<file_path>, where <file_path> /// is taken from the response. It is guaranteed that the link will be valid for at least 1 hour. - /// When the link expires, a new one can be requested by calling again. + /// When the link expires, a new one can be requested by calling + /// again. /// /// /// You can use or @@ -2464,7 +2476,8 @@ await botClient.ThrowIfNull() /// /// Use this method to create an additional invite link for a chat. The bot must be an administrator /// in the chat for this to work and must have the appropriate admin rights. The link can be revoked - /// using the method + /// using the method + /// /// /// An instance of /// @@ -2985,8 +2998,9 @@ await botClient.ThrowIfNull() /// /// Use this method to set a new group sticker set for a supergroup. The bot must be an administrator in the /// chat for this to work and must have the appropriate admin rights. Use the field - /// optionally returned in requests to check - /// if the bot can use this method. + /// optionally returned in + /// requests to check if the bot + /// can use this method. /// /// An instance of /// @@ -3014,8 +3028,9 @@ await botClient.ThrowIfNull() /// /// Use this method to delete a group sticker set from a supergroup. The bot must be an administrator in the /// chat for this to work and must have the appropriate admin rights. Use the field - /// optionally returned in requests to - /// check if the bot can use this method + /// optionally returned in + /// requests to check if the bot + /// can use this method /// /// An instance of /// @@ -3068,7 +3083,8 @@ await botClient.ThrowIfNull() /// 13338331 (0xCB86DB), 9367192 (0x8EEE98), 16749490 (0xFF93B2), or 16478047 (0xFB6F5F) /// /// - /// Unique identifier of the custom emoji shown as the topic icon. Use + /// Unique identifier of the custom emoji shown as the topic icon. Use + /// /// to get all allowed custom emoji identifiers /// /// @@ -4333,8 +4349,9 @@ await botClient.ThrowIfNull() /// (in the format @channelusername) /// /// - /// Identifiers of 1-100 messages to delete. See - /// for limitations on which messages can be deleted + /// Identifiers of 1-100 messages to delete. See + /// for limitations + /// on which messages can be deleted /// /// /// A cancellation token that can be used by other objects or threads to receive notice of cancellation From 65aebec9e0b2914d5cb940c69f87b53cb27ce1fa Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 04:10:51 +0400 Subject: [PATCH 85/90] Fix XML documentation --- src/Telegram.Bot/Types/File.cs | 13 ++++++++++--- src/Telegram.Bot/Types/FileBase.cs | 8 ++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Telegram.Bot/Types/File.cs b/src/Telegram.Bot/Types/File.cs index e072c2a1c..b80119c1c 100644 --- a/src/Telegram.Bot/Types/File.cs +++ b/src/Telegram.Bot/Types/File.cs @@ -1,14 +1,21 @@ +using System.Threading; +using Telegram.Bot.Requests; + namespace Telegram.Bot.Types; /// -/// This object represents a file ready to be downloaded. The file can be downloaded via . -/// It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested by calling . +/// This object represents a file ready to be downloaded. The file can be downloaded via +/// . +/// It is guaranteed that the link will be valid for at least 1 hour. When the link expires, a new one can be requested +/// by calling . /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public class File : FileBase { /// - /// Optional. File path. Use to get the file. + /// Optional. File path. Use + /// + /// to get the file. /// [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)] public string? FilePath { get; set; } diff --git a/src/Telegram.Bot/Types/FileBase.cs b/src/Telegram.Bot/Types/FileBase.cs index 7132acfba..5b4a91ae9 100644 --- a/src/Telegram.Bot/Types/FileBase.cs +++ b/src/Telegram.Bot/Types/FileBase.cs @@ -1,10 +1,14 @@ +using System.Threading; +using Telegram.Bot.Requests; + namespace Telegram.Bot.Types; /// /// This object represents a file ready to be downloaded. The file can be downloaded via -/// . It is guaranteed that the link will be valid for +/// . +/// It is guaranteed that the link will be valid for /// at least 1 hour. When the link expires, a new one can be requested by calling -/// . +/// . /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] public abstract class FileBase From d97a212881e467c56891d594c19f89082489bd56 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 04:11:24 +0400 Subject: [PATCH 86/90] Use target-new for requests --- .../Exceptions/ApiExceptionsTests2.cs | 2 +- test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs | 4 ++-- test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs | 8 ++++---- .../Location/InlineMessageLiveLocationTests .cs | 4 ++-- .../Location/LiveLocationTests.cs | 2 +- .../Update Messages/EditMessageContentTests.cs | 6 +++--- .../Update Messages/EditMessageContentTests2.cs | 4 ++-- .../Update Messages/EditMessageMediaTests.cs | 4 ++-- .../Update Messages/EditMessageMediaTests2.cs | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs index d2e17729f..179449bbe 100644 --- a/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Exceptions/ApiExceptionsTests2.cs @@ -88,7 +88,7 @@ public async Task Should_Throw_Exception_MessageIsNotModifiedException() ApiRequestException e = await Assert.ThrowsAsync(() => BotClient.EditMessageTextAsync( - new EditMessageTextRequest + new() { ChatId = fixture.SupergroupChat.Id, MessageId = message.MessageId, diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs index 6c9ca7b09..b2a5f1159 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests.cs @@ -64,7 +64,7 @@ await fixture.UpdateReceiver.GetInlineQueryResultUpdates( public async Task Should_Get_High_Scores_Inline_Message() { GameHighScore[] highScores = await BotClient.GetInlineGameHighScoresAsync( - new GetInlineGameHighScoresRequest + new() { UserId = classFixture.Player.Id, InlineMessageId = classFixture.InlineGameMessageId, @@ -91,7 +91,7 @@ await fixture.SendTestInstructionsAsync( ); await BotClient.SetInlineGameScoreAsync( - new SetInlineGameScoreRequest + new() { UserId = playerId, Score = newScore, diff --git a/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs b/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs index dc84ebed1..29308f7fa 100644 --- a/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Games/GamesTests2.cs @@ -74,7 +74,7 @@ public async Task Should_Send_Game_With_ReplyMarkup() public async Task Should_Get_High_Scores() { GameHighScore[] highScores = await BotClient.GetGameHighScoresAsync( - new GetGameHighScoresRequest + new() { UserId = classFixture.Player.Id, ChatId = fixture.SupergroupChat.Id, @@ -110,7 +110,7 @@ await fixture.SendTestInstructionsAsync( ); Message gameMessage = await BotClient.SetGameScoreAsync( - new SetGameScoreRequest + new() { UserId = playerId, Score = newScore, @@ -124,7 +124,7 @@ await fixture.SendTestInstructionsAsync( // update the high scores cache await Task.Delay(1_000); classFixture.HighScores = await BotClient.GetGameHighScoresAsync( - new GetGameHighScoresRequest + new() { UserId = playerId, ChatId = fixture.SupergroupChat.Id, @@ -146,7 +146,7 @@ await fixture.SendTestInstructionsAsync( ); Message gameMessage = await BotClient.SetGameScoreAsync( - new SetGameScoreRequest + new() { UserId = playerId, Score = newScore, diff --git a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs index eed141fa5..3ef0a11bc 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs +++ b/test/Telegram.Bot.Tests.Integ/Location/InlineMessageLiveLocationTests .cs @@ -66,7 +66,7 @@ public async Task Should_Edit_Inline_Message_Live_Location() Location beijing = new() { Latitude = 39.9042f, Longitude = 116.4074f }; await BotClient.EditInlineMessageLiveLocationAsync( - new EditInlineMessageLiveLocationRequest + new() { InlineMessageId = cqUpdate.CallbackQuery!.InlineMessageId!, Latitude = beijing.Latitude, @@ -83,7 +83,7 @@ await BotClient.EditInlineMessageLiveLocationAsync( public async Task Should_Stop_Inline_Message_Live_Location() { await BotClient.StopInlineMessageLiveLocationAsync( - new StopInlineMessageLiveLocationRequest + new() { InlineMessageId = classFixture.InlineMessageId, } diff --git a/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs b/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs index c31226935..bf09ad6d4 100644 --- a/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Location/LiveLocationTests.cs @@ -62,7 +62,7 @@ public async Task Should_Update_Live_Location() await Task.Delay(1_500); editedMessage = await BotClient.EditMessageLiveLocationAsync( - new EditMessageLiveLocationRequest + new() { ChatId = LocationMessage.Chat.Id, MessageId = LocationMessage.MessageId, diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs index 25b50e781..c26711d53 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests.cs @@ -78,7 +78,7 @@ await BotClient.AnswerInlineQueryAsync( messageText = $"{modifiedMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; await BotClient.EditInlineMessageTextAsync( - new EditInlineMessageTextRequest + new() { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, Text = messageText, @@ -143,7 +143,7 @@ await BotClient.AnswerInlineQueryAsync( Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); await BotClient.EditInlineMessageReplyMarkupAsync( - new EditInlineMessageReplyMarkupRequest + new() { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, ReplyMarkup = "✌ Edited 👌", @@ -203,7 +203,7 @@ await BotClient.AnswerInlineQueryAsync( Assert.NotNull(callbackQUpdate.CallbackQuery.InlineMessageId); await BotClient.EditInlineMessageCaptionAsync( - new EditInlineMessageCaptionRequest + new() { InlineMessageId = callbackQUpdate.CallbackQuery.InlineMessageId, Caption = "_Caption is edited_ 👌", diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs index eee88e4ce..7af3d2554 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageContentTests2.cs @@ -44,7 +44,7 @@ public async Task Should_Edit_Message_Text() messageText = $"{modifiedMessagePrefix}{string.Join("\n", entityValueMappings.Select(tuple => tuple.Value))}"; Message editedMessage = await BotClient.EditMessageTextAsync( - new EditMessageTextRequest + new() { ChatId = originalMessage.Chat.Id, MessageId = originalMessage.MessageId, @@ -122,7 +122,7 @@ public async Task Should_Edit_Message_Caption() string caption = $"{captionPrefix} {captionEntity.Value}"; Message editedMessage = await BotClient.EditMessageCaptionAsync( - new EditMessageCaptionRequest + new() { ChatId = originalMessage.Chat.Id, MessageId = originalMessage.MessageId, diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs index 235f73656..270bee37b 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests.cs @@ -65,7 +65,7 @@ await BotClient.AnswerInlineQueryAsync( // either an URL or the file_id of a previously uploaded media. InputFileUrl inputFileUrl = InputFile.FromUri("https://upload.wikimedia.org/wikipedia/commons/transcoded/b/bb/Test_ogg_mp3_48kbps.wav/Test_ogg_mp3_48kbps.wav.mp3"); await BotClient.EditInlineMessageMediaAsync( - new EditInlineMessageMediaRequest + new() { InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, Media = new InputMediaAudio @@ -138,7 +138,7 @@ await BotClient.AnswerInlineQueryAsync( // should be either an URL or the file_id of a previously uploaded media. // Also, animation thumbnail cannot be uploaded for an inline message. await BotClient.EditInlineMessageMediaAsync( - new EditInlineMessageMediaRequest + new() { InlineMessageId = cqUpdate.CallbackQuery.InlineMessageId, Media = new InputMediaAnimation { Media = InputFile.FromFileId(animationFileId) }, diff --git a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs index c42bd1dcb..26f19f17a 100644 --- a/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs +++ b/test/Telegram.Bot.Tests.Integ/Update Messages/EditMessageMediaTests2.cs @@ -41,7 +41,7 @@ public async Task Should_Edit_Message_Video() await using (Stream stream = System.IO.File.OpenRead(Constants.PathToFile.Certificate.PublicKey)) { editedMessage = await BotClient.EditMessageMediaAsync( - new EditMessageMediaRequest + new() { ChatId = originalMessage.Chat, MessageId = originalMessage.MessageId, @@ -95,7 +95,7 @@ public async Task Should_Edit_Message_Photo() // Replace audio with another audio by uploading the new file. A thumbnail image is also uploaded. await using Stream thumbStream = System.IO.File.OpenRead(Constants.PathToFile.Thumbnail.Video); Message editedMessage = await BotClient.EditMessageMediaAsync( - new EditMessageMediaRequest + new() { ChatId = originalMessage.Chat, MessageId = originalMessage.MessageId, From 47fe66f2dbda6c490edc2c601d457e3041d5d58a Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 04:14:10 +0400 Subject: [PATCH 87/90] use version suffix --- .azure-pipelines/variables.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/variables.yml b/.azure-pipelines/variables.yml index 1631b5aae..f26fdfe0c 100644 --- a/.azure-pipelines/variables.yml +++ b/.azure-pipelines/variables.yml @@ -3,7 +3,7 @@ variables: - name: versionPrefix value: 20.0.0 - name: versionSuffix - value: '' + value: 'alpha.3' - name: ciVersionSuffix value: ci.$(Build.BuildId)+git.commit.$(Build.SourceVersion) - name: isPreRelease From 22a3d478e126f766bd1ed0c022407c74035c9176 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sat, 2 Mar 2024 04:30:08 +0400 Subject: [PATCH 88/90] Updated CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd30a98dc..6bc00a03b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,8 @@ in the class `Update`. The bot must be an administrator in the chat to receive t - Fields `Chat` and `Id` to type `Story` ### Changed +- All required properties without setters marked as required using `required` keyword +- All non-default ctors are marked as obsolete in favor of the default ctors with object initialization syntax and required properties - All API methods with positional parameters on `ITelegramBotClient` are marked obsolete - Class `UnpinAllGeneralForumTopicMessages` marked as obsolete - Replaced parameters `ReplyToMessageId` and `AllowSendingWithoutReply` with the property `ReplyParameters` of type `ReplyParameters` in the methods From e5d3d1635cc8f4f67ea563b5d6a3ce3e7d70d914 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 3 Mar 2024 02:30:39 +0400 Subject: [PATCH 89/90] Add readme to the resulting nuget package --- src/Telegram.Bot/Telegram.Bot.csproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Telegram.Bot/Telegram.Bot.csproj b/src/Telegram.Bot/Telegram.Bot.csproj index 437e94ca9..23caa6dc8 100644 --- a/src/Telegram.Bot/Telegram.Bot.csproj +++ b/src/Telegram.Bot/Telegram.Bot.csproj @@ -23,6 +23,7 @@ RoundRobin,Poulad,tuscen Copyright © Robin Müller 2016 package-icon.png + README.md https://github.com/TelegramBots/telegram.bot MIT https://github.com/TelegramBots/telegram.bot.git @@ -64,6 +65,7 @@ true / + From 885de13882e48793dbe69ac6557c5286e3dda472 Mon Sep 17 00:00:00 2001 From: Aleksey Usatov Date: Sun, 3 Mar 2024 02:31:05 +0400 Subject: [PATCH 90/90] Use an enum for chat boost source instead of a string --- CHANGELOG.md | 1 + .../Converters/ChatBoostSourceConverter.cs | 11 +- src/Telegram.Bot/Types/ChatBoostSource.cs | 17 +- .../Types/Enums/ChatBoostSourceType.cs | 24 ++ .../ChatBoostSourceTypeConverterTests.cs | 65 ++++++ .../ChatMemberSerializationTests.cs | 29 ++- .../ChatSourceBoostSerializationTests.cs | 208 ++++++++++++++++++ 7 files changed, 327 insertions(+), 28 deletions(-) create mode 100644 src/Telegram.Bot/Types/Enums/ChatBoostSourceType.cs create mode 100644 test/Telegram.Bot.Tests.Unit/EnumConverter/ChatBoostSourceTypeConverterTests.cs create mode 100644 test/Telegram.Bot.Tests.Unit/Serialization/ChatSourceBoostSerializationTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bc00a03b..feea649b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/). - Class `UnpinAllGeneralForumTopicMessagesRequest` - The classes `ReactionType`, `ReactionTypeEmoji` and `ReactionTypeCustomEmoji` representing different types of reaction. - Enum `ReactionTypeKind` +- Enum `ChatBoostSourceType` - The class `KnownReactionTypeEmoji` containing Emojis available for `ReactionTypeEmoji`. - Updates about a reaction change on a message with non-anonymous reactions, represented by the class `MessageReactionUpdated` and the property `MessageReaction` in the class `Update`. The bot must explicitly allow the update to receive it. diff --git a/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs b/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs index 76afd5464..fc1e79983 100644 --- a/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs +++ b/src/Telegram.Bot/Converters/ChatBoostSourceConverter.cs @@ -1,5 +1,6 @@ using System.Reflection; using Newtonsoft.Json.Linq; +using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Converters; @@ -32,7 +33,7 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer JsonSerializer serializer) { var jo = JObject.Load(reader); - var type = jo["source"]?.Value(); + var type = jo["source"]?.ToObject(); if (type is null) { @@ -41,10 +42,10 @@ public override void WriteJson(JsonWriter writer, object? value, JsonSerializer var actualType = type switch { - "premium" => typeof(ChatBoostSourcePremium), - "gift_code" => typeof(ChatBoostSourceGiftCode), - "giveaway" => typeof(ChatBoostSourceGiveaway), - _ => throw new JsonSerializationException($"Unknown chat boost source value of '{jo["source"]}'") + ChatBoostSourceType.Premium => typeof(ChatBoostSourcePremium), + ChatBoostSourceType.GiftCode => typeof(ChatBoostSourceGiftCode), + ChatBoostSourceType.Giveaway => typeof(ChatBoostSourceGiveaway), + _ => throw new JsonSerializationException($"Unknown chat boost source value of '{jo["source"]}'") }; // Remove status because status property only has getter diff --git a/src/Telegram.Bot/Types/ChatBoostSource.cs b/src/Telegram.Bot/Types/ChatBoostSource.cs index 31d28cc7b..89790bad4 100644 --- a/src/Telegram.Bot/Types/ChatBoostSource.cs +++ b/src/Telegram.Bot/Types/ChatBoostSource.cs @@ -1,4 +1,5 @@ using Telegram.Bot.Converters; +using Telegram.Bot.Types.Enums; namespace Telegram.Bot.Types; @@ -18,19 +19,19 @@ public abstract class ChatBoostSource /// Source of the boost /// [JsonProperty] - public abstract string Source { get; } + public abstract ChatBoostSourceType Source { get; } } /// /// The boost was obtained by subscribing to Telegram Premium or by gifting a Telegram Premium subscription to another user. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public abstract class ChatBoostSourcePremium : ChatBoostSource +public class ChatBoostSourcePremium : ChatBoostSource { /// /// Source of the boost, always "premium" /// - public override string Source => "premium"; + public override ChatBoostSourceType Source => ChatBoostSourceType.Premium; /// /// User that boosted the chat @@ -44,12 +45,12 @@ public abstract class ChatBoostSourcePremium : ChatBoostSource /// Each such code boosts the chat 4 times for the duration of the corresponding Telegram Premium subscription. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public abstract class ChatBoostSourceGiftCode : ChatBoostSource +public class ChatBoostSourceGiftCode : ChatBoostSource { /// /// Source of the boost, always "gift_code" /// - public override string Source => "gift_code"; + public override ChatBoostSourceType Source => ChatBoostSourceType.GiftCode; /// /// User for which the gift code was created @@ -63,19 +64,19 @@ public abstract class ChatBoostSourceGiftCode : ChatBoostSource /// This boosts the chat 4 times for the duration of the corresponding Telegram Premium subscription. /// [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] -public abstract class ChatBoostSourceGiveaway : ChatBoostSource +public class ChatBoostSourceGiveaway : ChatBoostSource { /// /// Source of the boost, always "giveaway" /// - public override string Source => "giveaway"; + public override ChatBoostSourceType Source => ChatBoostSourceType.Giveaway; /// /// Identifier of a message in the chat with the giveaway; the message could have been deleted already. /// May be 0 if the message isn't sent yet. /// [JsonProperty(Required = Required.Always)] - public int GiveawayMessageId { get; set; } = default!; + public int GiveawayMessageId { get; set; } /// /// Optional. User that won the prize in the giveaway if any diff --git a/src/Telegram.Bot/Types/Enums/ChatBoostSourceType.cs b/src/Telegram.Bot/Types/Enums/ChatBoostSourceType.cs new file mode 100644 index 000000000..b25bab360 --- /dev/null +++ b/src/Telegram.Bot/Types/Enums/ChatBoostSourceType.cs @@ -0,0 +1,24 @@ +namespace Telegram.Bot.Types.Enums; + +/// +/// Type of chat boost source +/// +[JsonConverter(typeof(ChatBoostSourceTypeConverter))] +public enum ChatBoostSourceType +{ + /// + /// The boost was obtained by subscribing to Telegram Premium + /// or by gifting a Telegram Premium subscription to another user + /// + Premium = 1, + + /// + /// The boost was obtained by the creation of Telegram Premium gift codes to boost a chat + /// + GiftCode, + + /// + /// The boost was obtained by the creation of a Telegram Premium giveaway + /// + Giveaway, +} diff --git a/test/Telegram.Bot.Tests.Unit/EnumConverter/ChatBoostSourceTypeConverterTests.cs b/test/Telegram.Bot.Tests.Unit/EnumConverter/ChatBoostSourceTypeConverterTests.cs new file mode 100644 index 000000000..4941e5bc5 --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/EnumConverter/ChatBoostSourceTypeConverterTests.cs @@ -0,0 +1,65 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using System; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.EnumConverter; + +public class ChatBoostSourceTypeConverterTests +{ + [Theory] + [InlineData(ChatBoostSourceType.Giveaway, "giveaway")] + [InlineData(ChatBoostSourceType.Premium, "premium")] + [InlineData(ChatBoostSourceType.GiftCode, "gift_code")] + public void Should_Convert_ChatBoostSourceType_To_String(ChatBoostSourceType kind, string value) + { + Container container = new() { Type = kind }; + string expectedResult = @$"{{""type"":""{value}""}}"; + + string result = JsonConvert.SerializeObject(container); + + Assert.Equal(expectedResult, result); + } + + [Theory] + [InlineData(ChatBoostSourceType.Giveaway, "giveaway")] + [InlineData(ChatBoostSourceType.Premium, "premium")] + [InlineData(ChatBoostSourceType.GiftCode, "gift_code")] + public void Should_Convert_String_ToChatBoostSourceType(ChatBoostSourceType kind, string value) + { + Container expectedResult = new() { Type = kind }; + string jsonData = @$"{{""type"":""{value}""}}"; + + Container? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal(expectedResult.Type, result.Type); + } + + [Fact] + public void Should_Return_Zero_For_Incorrect_ChatBoostSourceType() + { + string jsonData = @$"{{""type"":""{int.MaxValue}""}}"; + + Container? result = JsonConvert.DeserializeObject(jsonData); + + Assert.NotNull(result); + Assert.Equal((ChatBoostSourceType)0, result.Type); + } + + [Fact] + public void Should_Throw_NotSupportedException_For_Incorrect_ChatBoostSourceType() + { + Container container = new() { Type = (ChatBoostSourceType)int.MaxValue }; + + Assert.Throws(() => JsonConvert.SerializeObject(container)); + } + + [JsonObject(MemberSerialization.OptIn, NamingStrategyType = typeof(SnakeCaseNamingStrategy))] + class Container + { + [JsonProperty(Required = Required.Always)] + public ChatBoostSourceType Type { get; init; } + } +} diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs index 12af9f664..d4be6d138 100644 --- a/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatMemberSerializationTests.cs @@ -13,24 +13,23 @@ public class ChatMemberSerializationTests [Fact] public void Should_Deserialize_Chat_Member_Member() { - var creator = new + const string json = """ { - status = ChatMemberStatus.Creator, - user = new - { - id = 12345, - is_bot = true, - first_name = "First Name", - last_name = "Last Name", - username = "test_bot", - language_code = "en_US", + "status": "creator", + "user": { + "id": 12345, + "is_bot": true, + "first_name": "First Name", + "last_name": "Last Name", + "username": "test_bot", + "language_code": "en_US", }, - is_anonymous = true, - custom_title = "custom test title" - }; + "is_anonymous": true, + "custom_title": "custom test title" + } + """; - string? chatMemberJson = JsonConvert.SerializeObject(creator, Formatting.Indented); - ChatMember? chatMember = JsonConvert.DeserializeObject(chatMemberJson); + ChatMember? chatMember = JsonConvert.DeserializeObject(json); ChatMemberOwner owner = Assert.IsType(chatMember); diff --git a/test/Telegram.Bot.Tests.Unit/Serialization/ChatSourceBoostSerializationTests.cs b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSourceBoostSerializationTests.cs new file mode 100644 index 000000000..61d2274ec --- /dev/null +++ b/test/Telegram.Bot.Tests.Unit/Serialization/ChatSourceBoostSerializationTests.cs @@ -0,0 +1,208 @@ +using System; +using System.Linq; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Xunit; + +namespace Telegram.Bot.Tests.Unit.Serialization; + +public class ChatSourceBoostSerializationTests +{ + [Fact] + public void Should_Serialize_ChatBoostSourcePremium() + { + ChatBoostSourcePremium creator = new() + { + User = new() + { + Id = 12345, + IsBot = true, + FirstName = "First Name", + LastName = "Last Name", + Username = "test_bot", + LanguageCode = "en_US", + }, + }; + + string chatMemberJson = JsonConvert.SerializeObject(creator); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(2, j.Children().Count()); + Assert.Equal("premium", j["source"]); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); + } + + [Fact] + public void Should_Serialize_ChatBoostSourceGiveaway() + { + ChatBoostSourceGiveaway creator = new() + { + User = new() + { + Id = 12345, + IsBot = true, + FirstName = "First Name", + LastName = "Last Name", + Username = "test_bot", + LanguageCode = "en_US", + }, + GiveawayMessageId = 654321, + IsUnclaimed = true, + }; + + string chatMemberJson = JsonConvert.SerializeObject(creator); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(4, j.Children().Count()); + Assert.Equal("giveaway", j["source"]); + Assert.Equal(654321, j["giveaway_message_id"]); + Assert.Equal(true, j["is_unclaimed"]); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); + } + + [Fact] + public void Should_Serialize_ChatBoostSourceGiftCode() + { + ChatBoostSourceGiftCode creator = new() + { + User = new() + { + Id = 12345, + IsBot = true, + FirstName = "First Name", + LastName = "Last Name", + Username = "test_bot", + LanguageCode = "en_US", + }, + }; + + string chatMemberJson = JsonConvert.SerializeObject(creator); + JObject j = JObject.Parse(chatMemberJson); + + Assert.Equal(2, j.Children().Count()); + + JToken? ju = j["user"]; + Assert.NotNull(ju); + + Assert.Equal(6, ju.Children().Count()); + Assert.Equal(12345, ju["id"]); + Assert.Equal(true, ju["is_bot"]); + Assert.Equal("First Name", ju["first_name"]); + Assert.Equal("Last Name", ju["first_name"]); + Assert.Equal("test_bot", ju["username"]); + Assert.Equal("en_US", ju["language_code"]); + } + + [Fact] + public void Should_Deserialize_ChatBoostPremium() + { + const string json = """ + { + "source": "premium", + "user": { + "id": 123, + "is_premium": true, + "is_bot": false, + "first_name": "Test User" + } + } + """; + + ChatBoostSource? boostSource = JsonConvert.DeserializeObject(json); + + ChatBoostSourcePremium premium = Assert.IsAssignableFrom(boostSource); + + Assert.Equal(ChatBoostSourceType.Premium, premium.Source); + Assert.Equal(123, premium.User.Id); + Assert.True(premium.User.IsPremium); + Assert.NotNull(premium.User); + Assert.Equal("Test User", premium.User.FirstName); + } + + + [Fact] + public void Should_Deserialize_ChatBoostSourceGiftCode() + { + string json = """ + { + "source": "gift_code", + "user": { + "id": 12345, + "is_bot": true, + "first_name": "First Name", + "last_name": "Last Name", + "username": "test_bot", + "language_code": "en_US" + } + } + """; + + ChatBoostSourceGiftCode? giveaway = JsonConvert.DeserializeObject(json); + + Assert.NotNull(giveaway); + Assert.Equal(ChatBoostSourceType.GiftCode, giveaway.Source); + Assert.NotNull(giveaway.User); + Assert.Equal(12345, giveaway.User.Id); + Assert.True(giveaway.User.IsBot); + Assert.Equal("First Name", giveaway.User.FirstName); + Assert.Equal("Last Name", giveaway.User.LastName); + Assert.Equal("test_bot", giveaway.User.Username); + Assert.Equal("en_US", giveaway.User.LanguageCode); + } + + [Fact] + public void Should_Deserialize_ChatBoostSourceGiveaway() + { + string json = """ + { + "source": "giveaway", + "giveaway_message_id": 12345, + "is_unclaimed": true, + "user": { + "id": 12345, + "is_bot": true, + "first_name": "First Name", + "last_name": "Last Name", + "username": "test_bot", + "language_code": "en_US" + } + } + """; + + ChatBoostSourceGiveaway? giveaway = JsonConvert.DeserializeObject(json); + + Assert.NotNull(giveaway); + Assert.Equal(ChatBoostSourceType.Giveaway, giveaway.Source); + Assert.True(giveaway.IsUnclaimed); + Assert.Equal(12345, giveaway.GiveawayMessageId); + Assert.NotNull(giveaway.User); + Assert.Equal(12345, giveaway.User.Id); + Assert.True(giveaway.User.IsBot); + Assert.Equal("First Name", giveaway.User.FirstName); + Assert.Equal("Last Name", giveaway.User.LastName); + Assert.Equal("test_bot", giveaway.User.Username); + Assert.Equal("en_US", giveaway.User.LanguageCode); + } +}