Exemplo n.º 1
0
        public async Task Should_Remove_Profile()
        {
            // user sends a new text message with the text "forget me"
            // replying to the profile removal prompt message from the BusVbot
            string update = @"{
                update_id: 1,
                message: {
                    message_id: 22,
                    text: ""forget me"",
                    chat: {
                        id: 789,
                        type: ""private""
                    },
                    from: {
                        id: 789,
                        first_name: ""Jack"",
                        is_bot: false
                    },
                    reply_to_message: {
                        message_id: 18,
                        text: ""Are you sure you want to remove your profile?"",
                        chat: {
                            id: 789,
                            type: ""private""
                        },
                        from: {
                            id: 420,
                            first_name: ""BusVbot"",
                            is_bot: true,
                            username: ""busvbot""
                        },
                        date: 2568
                    },
                    date: 2680
                }
            }";

            // ensure user profile is persisted in the db
            IUserProfileRepo userRepo = _fixture.Services.GetRequiredService <IUserProfileRepo>();
            await userRepo.DeleteAsync("789", "789");

            await userRepo.AddAsync(new UserProfile
            {
                ChatId           = "789",
                UserId           = "789",
                DefaultAgencyTag = "lametro"
            });

            // ensure some value is set in the cache
            await _fixture.Cache.SetStringAsync(@"{""u"":1234,""c"":1234}", "{}");

            // should send a message acknowledging the profile removal
            _fixture.MockBotClient
            .Setup(botClient => botClient.SendTextMessageAsync(
                       /* chatId: */ Is.SameJson <ChatId>("789"),
                       /* text: */ "Your _profile is now removed_ but this doesn't need to be a goodbye! 😉\n\n" +
                       "Come back whenever you needed my services 🚍🏃 and we can start over again.",
                       /* parseMode: */ ParseMode.Markdown,
        public async Task Should_Set_User_Agency_TTC()
        {
            // ToDo remove msg date: https://github.com/TelegramBots/Telegram.Bot/issues/801
            // for the message in a callback query update, message content and message date will not be available
            // if the message is too old.
            string update = @"{
                update_id: 1,
                callback_query: {
                    id: ""5400"",
                    data: ""ups/a:Ttc"",
                    from: {
                        id: 1234,
                        first_name: ""Poulad"",
                        is_bot: false
                    },
                    message: {
                        message_id: 2744,
                        date: 200,
                        from: {
                            id: 1234,
                            first_name: ""Poulad"",
                            is_bot: false
                        },
                        chat: {
                            id: 1234,
                            type: ""private""
                        }
                    },
                    chat_instance: ""-9999"",
                    date: 1100
                }
            }";

            // ensure user profile does not exist in the db
            IUserProfileRepo userRepo = _fixture.Services.GetRequiredService <IUserProfileRepo>();
            await userRepo.DeleteAsync("1234", "1234");

            // ensure cache is set
            await _fixture.Cache.SetStringAsync(
                @"{""u"":1234,""c"":1234}",
                @"{""ProfileSetup"":{""IsInstructionsSent"":true}}"
                );

            // should send a message acknowledging that the new agency is set
            _fixture.MockBotClient
            .Setup(botClient => botClient.SendTextMessageAsync(
                       /* chatId: */ Is.SameJson <ChatId>("1234"),
                       /* text: */ "Great! Your default agency is now set to *Toronto Transit Commission* " +
                       "in Ontario, Canada.\n\n\n" +
                       "💡 *Pro Tip*: You can always view or modify it using the /profile command.",
                       /* parseMode: */ ParseMode.Markdown,
        /// <summary>
        /// Removes the user profile from the database and the cache
        /// </summary>
        public async Task HandleAsync(IUpdateContext context, UpdateDelegate next, CancellationToken cancellationToken)
        {
            if (context.Update.Message.Text.Equals("forget me", StringComparison.OrdinalIgnoreCase))
            {
                _logger.LogTrace("Removing the user profile from the database and the cache");

                var userchat = context.Update.ToUserchat();

                bool isDeleted = await _userProfileRepo.DeleteAsync(
                    userchat.UserId.ToString(),
                    userchat.ChatId.ToString(),
                    cancellationToken
                    ).ConfigureAwait(false);

                if (isDeleted)
                {
                    await _cache.RemoveAsync(userchat, cancellationToken)
                    .ConfigureAwait(false);

                    await context.Bot.Client.SendTextMessageAsync(
                        context.Update.Message.Chat,
                        "Your _profile is now removed_ but this doesn't need to be a goodbye! 😉\n\n" +
                        "Come back whenever you needed my services 🚍🏃 and we can start over again.",
                        ParseMode.Markdown,
                        cancellationToken : cancellationToken
                        );

                    context.Items[nameof(WebhookResponse)] = new DeleteMessageRequest(
                        context.Update.Message.Chat,
                        context.Update.Message.ReplyToMessage.MessageId
                        );
                }
                else
                {
                    // ToDo error. it should've been deleted
                }
            }
            else
            {
                _logger.LogTrace("Ignoring invalid message text.");

                context.Items[nameof(WebhookResponse)] = new SendChatActionRequest(
                    context.Update.Message.Chat,
                    ChatAction.Typing
                    );
            }
        }
Exemplo n.º 4
0
        public async Task Should_Send_Profile_Setup_Instructions()
        {
            string update = @"{
                update_id: 1,
                message: {
                    message_id: 2,
                    text: ""let's get started"",
                    chat: {
                        id: 1234,
                        type: ""private""
                    },
                    from: {
                        id: 1234,
                        first_name: ""Poulad"",
                        is_bot: false
                    },
                    date: 1000
                }
            }";

            // ensure user profile does not exist in the db
            IUserProfileRepo userRepo = _fixture.Services.GetRequiredService <IUserProfileRepo>();
            await userRepo.DeleteAsync("1234", "1234");

            // ensure cache is clear
            await _fixture.Cache.RemoveAsync(@"{""u"":1234,""c"":1234,""k"":""profile""}");

            // should send the first message with the country inline buttons
            _fixture.MockBotClient
            .Setup(botClient => botClient.MakeRequestAsync(
                       Is.SameJson <SendMessageRequest>($@"{{
                        chat_id: 1234,
                        text: ""Select a country and then a region to find your local transit agency"",
                        reply_markup: {{
                            inline_keyboard: [
                                [ {{ text: ""🇨🇦 Canada"", callback_data: ""ups/c:Canada"" }} ],
                                [ {{ text: ""🇺🇸 USA"", callback_data: ""ups/c:USA"" }} ],
                                [ {{ text: ""🏁 Test"", callback_data: ""ups/c:Test"" }} ]
                            ]
                        }}
                    }}"),
                       It.IsAny <CancellationToken>()
                       ))
            .ReturnsAsync(new Message {
                MessageId = 3
            });

            // should send the second message for sharing the location
            _fixture.MockBotClient
            .Setup(botClient => botClient.MakeRequestAsync(
                       Is.SameJson <SendMessageRequest>($@"{{
                        chat_id: 1234,
                        text: ""or *Share your location* so I can find it for you"",
                        parse_mode: ""Markdown"",
                        reply_markup: {{
                            keyboard: [ [ {{ text: ""Share my location"", request_location: true }} ] ],
                            resize_keyboard: true,
                            one_time_keyboard: true
                        }}
                    }}"),
                       It.IsAny <CancellationToken>()
                       ))
            .ReturnsAsync(new Message {
                MessageId = 4
            });

            HttpResponseMessage response = await _fixture.HttpClient.PostWebhookUpdateAsync(update);

            Assert.Equal(HttpStatusCode.Created, response.StatusCode);

            string responseContent = await response.Content.ReadAsStringAsync();

            Assert.Empty(responseContent);

            _fixture.MockBotClient.VerifyAll();
            _fixture.MockBotClient.VerifyNoOtherCalls();

            string cachedContext = await _fixture.Cache.GetStringAsync(@"{""u"":1234,""c"":1234,""k"":""profile""}");

            Asserts.JsonEqual(
                @"{""instructions_sent"":true,""agency_selection_msg"":3,""location_msg"":4}",
                cachedContext
                );
        }
Exemplo n.º 5
0
        public async Task Should_Cache_Location_Ask_For_Route()
        {
            // a location message
            string update = @"{
                update_id: 27,
                message: {
                    message_id: 45,
                    location: { latitude: 43.6606, longitude: -79.3852 },
                    chat: { id: 83, type: ""private"" },
                    from: { id: 83, first_name: ""Jack"", is_bot: false },
                    date: 46862680
                }
            }";

            // ensure user profile is persisted in the db
            IUserProfileRepo userRepo = _fixture.Services.GetRequiredService <IUserProfileRepo>();
            await userRepo.DeleteAsync("83", "83");

            await userRepo.AddAsync(new UserProfile
            {
                ChatId           = "83",
                UserId           = "83",
                DefaultAgencyTag = "ttc"
            });

            // ensure cache has no bus
            await _fixture.Cache.RemoveAsync(@"{""u"":83,""c"":83,""k"":""bus""}");

            // ensure cache has no location
            await _fixture.Cache.RemoveAsync(@"{""u"":83,""c"":83,""k"":""location""}");

            // should ask to choose the bus
            string text = "There you are! What's the bus you want to catch?\n" +
                          "Send me using 👉 /bus command.";

            _fixture.MockBotClient
            .Setup(botClient => botClient.MakeRequestAsync(
                       Is.SameJson <SendMessageRequest>($@"{{
                        chat_id: 83,
                        text: ""{text.Stringify()}"",
                        reply_to_message_id: 45,
                        reply_markup: {{ remove_keyboard: true }}
                    }}"),
                       It.IsAny <CancellationToken>()
                       ))
            .ReturnsAsync(null as Message);

            HttpResponseMessage response = await _fixture.HttpClient.PostWebhookUpdateAsync(update);

            Assert.Equal(HttpStatusCode.Created, response.StatusCode);

            string responseContent = await response.Content.ReadAsStringAsync();

            Assert.Empty(responseContent);

            _fixture.MockBotClient.VerifyAll();
            _fixture.MockBotClient.VerifyNoOtherCalls();

            // check whether location is cached
            string locationContext = await _fixture.Cache.GetStringAsync(@"{""u"":83,""c"":83,""k"":""location""}");

            Asserts.JsonEqual("{ location_msg: 45, lat: 43.6606, lon: -79.3852 }", locationContext);
        }