< Summary

Information
Class: TeleFlow.Telegram.Internal.TelegramStateKeyFactory
Assembly: TeleFlow.Framework
File(s): /_/src/TeleFlow.Framework/Internal/TelegramStateKeyFactory.cs
Line coverage
78%
Covered lines: 43
Uncovered lines: 12
Coverable lines: 55
Total lines: 143
Line coverage: 78.1%
Branch coverage
75%
Covered branches: 24
Total branches: 32
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%22100%
TryCreateStateKey(...)66.66%9655.55%
TryCreateFromMessage(...)100%44100%
TryCreateFromCallback(...)50%2275%
ResolveCallbackPartition(...)58.33%171266.66%
CreateUserSubject(...)100%11100%
CreateMessagePartition(...)100%44100%
CreateChatPartition(...)100%210%
CreateInlinePartition(...)100%11100%
CreatePartitionSegments(...)100%22100%

File(s)

/_/src/TeleFlow.Framework/Internal/TelegramStateKeyFactory.cs

#LineLine coverage
 1using TeleFlow.Framework.States;
 2using TeleFlow.Framework.Updates;
 3using TeleFlow.Telegram.Internal.Options;
 4using TeleFlow.Telegram.Schema.Types;
 5
 6namespace TeleFlow.Telegram.Internal;
 7
 8internal sealed class TelegramStateKeyFactory : IStateKeyFactory
 9{
 10    private readonly string? _botPartitionSegment;
 11
 12    public TelegramStateKeyFactory(TelegramStateKeyOptions options)
 13    {
 2014        ArgumentNullException.ThrowIfNull(options);
 15
 2016        _botPartitionSegment = options.BotId is { } botId ? $"bot:{botId}" : null;
 2017    }
 18
 19    public bool TryCreateStateKey(UpdateContext context, out StateKey key)
 20    {
 4121        ArgumentNullException.ThrowIfNull(context);
 22
 4123        if (context.Payload is not TelegramUpdatePayload payload)
 24        {
 025            key = default;
 026            return false;
 27        }
 28
 4129        if (TryCreateFromMessage(payload.Update.Message, out key) ||
 4130            TryCreateFromCallback(payload.Update.CallbackQuery, out key))
 31        {
 4132            return true;
 33        }
 34
 035        key = default;
 036        return false;
 37    }
 38
 39    private bool TryCreateFromMessage(Message? message, out StateKey key)
 40    {
 4141        if (message?.From is null)
 42        {
 343            key = default;
 344            return false;
 45        }
 46
 3847        key = StateKey.Create(
 3848            scope: "telegram",
 3849            subject: CreateUserSubject(message.From.Id),
 3850            partition: CreateMessagePartition(message));
 3851        return true;
 52    }
 53
 54    private bool TryCreateFromCallback(CallbackQuery? callbackQuery, out StateKey key)
 55    {
 356        if (callbackQuery is null)
 57        {
 058            key = default;
 059            return false;
 60        }
 61
 362        key = StateKey.Create(
 363            scope: "telegram",
 364            subject: CreateUserSubject(callbackQuery.From.Id),
 365            partition: ResolveCallbackPartition(callbackQuery));
 366        return true;
 67    }
 68
 69    private string ResolveCallbackPartition(CallbackQuery callbackQuery)
 70    {
 371        if (callbackQuery.Message is not null)
 72        {
 173            if (callbackQuery.Message.TryGetMessage(out var message) && message is not null)
 74            {
 175                return CreateMessagePartition(message);
 76            }
 77
 078            if (callbackQuery.Message.TryGetInaccessibleMessage(out var inaccessibleMessage) &&
 079                inaccessibleMessage is not null)
 80            {
 081                return CreateChatPartition(inaccessibleMessage.Chat.Id);
 82            }
 83        }
 84
 285        return string.IsNullOrWhiteSpace(callbackQuery.ChatInstance)
 286            ? CreateInlinePartition("unknown")
 287            : CreateInlinePartition(callbackQuery.ChatInstance);
 88    }
 89
 90    private static string CreateUserSubject(long userId)
 91    {
 4192        return $"user:{userId}";
 93    }
 94
 95    private string CreateMessagePartition(Message message)
 96    {
 3997        var segments = CreatePartitionSegments(capacity: 4);
 98
 3999        if (!string.IsNullOrWhiteSpace(message.BusinessConnectionId))
 100        {
 1101            segments.Add($"business:{message.BusinessConnectionId}");
 102        }
 103
 39104        segments.Add($"chat:{message.Chat.Id}");
 105
 39106        if (message.MessageThreadId is not null)
 107        {
 1108            segments.Add($"thread:{message.MessageThreadId.Value}");
 109        }
 110
 39111        return string.Join(':', segments);
 112    }
 113
 114    private string CreateChatPartition(long chatId)
 115    {
 0116        var segments = CreatePartitionSegments(capacity: 2);
 117
 0118        segments.Add($"chat:{chatId}");
 119
 0120        return string.Join(':', segments);
 121    }
 122
 123    private string CreateInlinePartition(string chatInstance)
 124    {
 2125        var segments = CreatePartitionSegments(capacity: 2);
 126
 2127        segments.Add($"inline:{chatInstance}");
 128
 2129        return string.Join(':', segments);
 130    }
 131
 132    private List<string> CreatePartitionSegments(int capacity)
 133    {
 41134        var segments = new List<string>(capacity);
 135
 41136        if (_botPartitionSegment is not null)
 137        {
 2138            segments.Add(_botPartitionSegment);
 139        }
 140
 41141        return segments;
 142    }
 143}