def test_creates_reminder_for_stock_shorting(self): assert Reminder.select().count() == 0 bot.reply_to_mentions() reminder = Reminder.select().first() assert reminder.short is True
def test_creates_reminder_when_mention_is_a_reply_to_another_tweet( self, mock_alpha_vantage_get_intraday): bot.reply_to_mentions() mock_alpha_vantage_get_intraday.assert_called_once_with("AMZN") assert Reminder.select().count() == 1 assert Reminder.select().first().tweet_id == 2
def test_creates_reminder_when_mention_is_a_reply_to_an_extended_tweet( self, mock_alpha_vantage_get_intraday, ): bot.reply_to_mentions() mock_alpha_vantage_get_intraday.assert_has_calls( [call("AMZN"), call("TSLA"), call("JNJ")]) assert Reminder.select().count() == 3 assert Reminder.select().first().tweet_id == 2
def test_creates_reminders_when_mention_contains_multiple_stocks_and_date( self, ): assert Reminder.select().count() == 0 bot.reply_to_mentions() reminders = Reminder.select() assert reminders.count() == 4 assert [reminder.stock_symbol for reminder in reminders] == [ "AMZN", "MSFT", "AAPL", "BABA", ]
async def pigeon_retrieve(self, ctx): """Retrieve and check on your pigeon.""" pigeon = ctx.pigeon if pigeon.status == Pigeon.Status.idle: raise SendableException(ctx.translate("pigeon_idle")) embed = self.get_base_embed(ctx.guild) activity = pigeon.current_activity if activity is None: raise SendableException(ctx.translate("nothing_to_retrieve")) if isinstance(activity, Exploration): if activity.end_date_passed: retrieval = ExplorationRetrieval(activity) embed = retrieval.embed retrieval.commit() return asyncio.gather(ctx.send(embed=embed)) else: embed.description = f"**{pigeon.name}** is still on {pigeon.gender.get_posessive_pronoun()} way to explore!" embed.set_footer( text="Check back at", icon_url= "https://www.animatedimages.org/data/media/678/animated-pigeon-image-0045.gif" ) embed.timestamp = activity.end_date return asyncio.gather(ctx.send(embed=embed)) elif isinstance(activity, Mail): if activity.end_date_passed: retrieval = MailRetrieval(activity) embed = retrieval.embed retrieval.commit() Reminder.create(user_id=activity.recipient.user_id, channel_id=None, dm=True, text=ctx.translate("pigeon_inbox_unread_mail"), due_date=datetime.datetime.utcnow()) return asyncio.gather(ctx.send(embed=embed)) else: embed.description = f"**{pigeon.name}** is still on {pigeon.gender.get_posessive_pronoun()} way to send a message!" embed.set_footer( text="Check back at", icon_url= "https://www.animatedimages.org/data/media/678/animated-pigeon-image-0045.gif" ) embed.timestamp = activity.end_date return asyncio.gather(ctx.send(embed=embed))
def test_does_not_publish_reminder_when_reminder_date_is_not_today( self, reminder, mock_tweepy): with freeze_time("2020-12-14T15:32:00Z"): bot.publish_reminders() mock_tweepy.assert_not_called() assert Reminder().get_by_id(reminder.id).is_finished is False
def test_creates_reminder_when_mention_contains_stock_and_date( self, mock_alpha_vantage_get_intraday): assert Reminder.select().count() == 0 with freeze_time("2020-12-13"): bot.reply_to_mentions() assert Reminder.select().count() == 1 reminder = Reminder.select().first() assert reminder.tweet_id == 1 assert reminder.created_on == date(2020, 12, 13) assert reminder.remind_on == date(2021, 3, 13) assert reminder.stock_symbol == "AMZN" assert reminder.stock_price == 3112.70 mock_alpha_vantage_get_intraday.assert_called_once_with("AMZN")
def test_creates_reminder_when_mention_contains_stock_and_date( self, mock_alpha_vantage_get_intraday_amazon): assert Reminder.select().count() == 0 with freeze_time("2020-12-13T15:32:00Z"): bot.reply_to_mentions() assert Reminder.select().count() == 1 reminder = Reminder.select().first() assert reminder.tweet_id == 1 assert reminder.created_on == date(2020, 12, 13) assert reminder.remind_on == "2021-03-13 15:32:00+00:00" assert reminder.stock_symbol == "AMZN" assert reminder.stock_price == 3112.70 assert reminder.is_finished is False mock_alpha_vantage_get_intraday_amazon.assert_called_once_with("AMZN")
def reminder(): return Reminder.create( user_name="user_name", tweet_id=1, created_on=date(2020, 10, 16), remind_on=date(2021, 1, 16), stock_symbol="AMZN", stock_price=2954.91, )
def reminder(): return Reminder.create( user_name="user_name", tweet_id=1, created_on=date(2020, 10, 16), remind_on=datetime(2021, 1, 16, 12, 0), stock_symbol="AMZN", stock_price=2954.91, is_finished=False, )
def test_replies_to_mention_when_mention_is_not_valid(self, mock_tweepy): with freeze_time("2020-12-13T15:32:00Z"): bot.reply_to_mentions() expected_status_call = call().update_status( status=f"@user_name {const.INVALID_MENTION_RESPONSE}", in_reply_to_status_id=1, ) assert expected_status_call in mock_tweepy.mock_calls assert Reminder.select().count() == 0
async def pigeon_explore(self, ctx): """Have your pigeon exploring countries.""" pigeon = ctx.pigeon human = ctx.human residence = human.country or Country.random() destination = Country.random() exploration = Exploration(residence=residence, destination=destination, pigeon=pigeon) exploration.end_date = exploration.start_date + datetime.timedelta( minutes=exploration.calculate_duration()) pigeon.status = Pigeon.Status.exploring pigeon.save() exploration.save() remind_emoji = "❗" embed = self.get_base_embed(ctx.guild) embed.description = "Okay. Your pigeon is now off to explore a random location!" embed.set_footer( text= f"React with {remind_emoji} to get reminded when available.\n'{ctx.prefix}pigeon retrieve' to check on your pigeon" ) message = await ctx.send(embed=embed) waiter = ReactionWaiter(ctx, message, emojis=(remind_emoji, ), members=(ctx.author, )) await waiter.add_reactions() emoji = await waiter.wait(remove=True) await waiter.clear_reactions() if emoji is not None: Reminder.create(user_id=ctx.author.id, channel_id=ctx.channel.id, text=ctx.translate("pigeon_ready_to_be_retrieved"), due_date=exploration.end_date) asyncio.gather(ctx.success(ctx.translate("reminder_created")))
def test_replies_to_mention_when_reminder_created(self, mock_tweepy): with freeze_time("2020-12-13T15:32:00Z"): bot.reply_to_mentions() expected_status_call = call().update_status( status= "@user_name Sure thing buddy! I'll remind you of the price of " "$AMZN on Saturday March 13 2021. I hope you make tons of money! 🤑", in_reply_to_status_id=1, ) assert Reminder.select().count() == 1 assert expected_status_call in mock_tweepy.mock_calls
def test_replies_with_help_message_when_mention_is_not_valid( self, mock_tweepy): bot.reply_to_mentions() expected_status_call = call().update_status( status="@user_name To create a reminder, mention me " "with one or more ticker symbols and a date. " "E.g. 'Remind me of $BTC in 3 months'. " "You can read about all my other features and " "implementation at: http://cutt.ly/Rh8CoJt", in_reply_to_status_id=1, ) assert expected_status_call in mock_tweepy.mock_calls assert Reminder.select().count() == 0
def test_replies_to_mention_when_reminder_created(self, mock_tweepy, mock_giphy): bot.reply_to_mentions() expected_calls = [ call().update_status( status= "@user_name Sure thing buddy! I'll remind you of the price of " "$AMZN on Thursday March 11 2021. I hope you make tons of money! 🤑", in_reply_to_status_id=1, ), ] assert Reminder.select().count() == 1 assert expected_calls in mock_tweepy.mock_calls
def test_publishes_reminder_when_reminder_date_is_today_and_stock_went_up( self, reminder, mock_tweepy): with freeze_time(reminder.remind_on): bot.publish_reminders() expected_calls = [ call().media_upload(filename=const.MR_SCROOGE_IMAGE_PATH), call().update_status( status="@user_name 3 months ago you bought $AMZN at $2,954.91. " "It is now worth $3,112.70. That's a return of 5.34%! 🚀🤑📈", media_ids=[ANY], in_reply_to_status_id=1, ), ] assert expected_calls in mock_tweepy.mock_calls assert Reminder().get_by_id(reminder.id).is_finished is True
def test_publishes_reminder_when_reminder_date_is_today_and_stock_went_down( self, reminder, mock_tweepy): reminder.stock_price = 3386.12 reminder.save() with freeze_time(reminder.remind_on): bot.publish_reminders() expected_calls = [ call().media_upload(filename=const.MR_BURNS_IMAGE_PATH), call().update_status( status="@user_name 3 months ago you bought $AMZN at $3,386.12. " "It is now worth $3,112.70. That's a return of -8.07%! ðŸ˜ðŸ“‰", media_ids=[ANY], in_reply_to_status_id=1, ), ] assert expected_calls in mock_tweepy.mock_calls assert Reminder().get_by_id(reminder.id).is_finished is True
async def reminder_notifier(self): query = Reminder.select() query = query.where(Reminder.finished == False) query = query.where(Reminder.due_date <= datetime.datetime.utcnow()) for reminder in query: sendable = reminder.sendable if sendable is not None: embed = discord.Embed(color=self.bot.get_dominant_color(None)) embed.set_author( name="Reminder", icon_url= "https://cdn.discordapp.com/attachments/744172199770062899/804862458070040616/1.webp" ) embed.description = reminder.text asyncio.gather( sendable.send(content=f"<@{reminder.user_id}>", embed=embed)) reminder.finished = True reminder.save()
def test_publishes_reminder_when_reminder_date_is_today_and_stock_was_split( self, reminder, mock_tweepy): reminder.created_on = date(2020, 8, 1) reminder.remind_on = datetime(2020, 12, 27, 12, 0) reminder.stock_symbol = "TSLA" reminder.stock_price = 2186.27 reminder.save() with freeze_time(reminder.remind_on): bot.publish_reminders() expected_calls = [ call().media_upload(filename=const.MR_SCROOGE_IMAGE_PATH), call().update_status( status="@user_name 4 months ago you bought $TSLA at $2,186.27 " "($437.25 after adjusting for the stock split). It is " "now worth $661.70. That's a return of 51.33%! 🚀🤑📈", media_ids=[ANY], in_reply_to_status_id=1, ), ] assert expected_calls in mock_tweepy.mock_calls assert Reminder().get_by_id(reminder.id).is_finished is True
def test_does_not_return_finished_reminders(self, reminder, time): reminder.finish() with freeze_time(time): assert Reminder.due_now().count() == 0
async def pigeon_mail(self, ctx, user: discord.User): """Sending someone a letter.""" if user.id == ctx.author.id: raise SendableException(ctx.translate("cannot_send_to_self")) sender = ctx.pigeon await ctx.send(ctx.translate("check_dms")) ctx.channel = ctx.author.dm_channel if ctx.channel is None: ctx.channel = await ctx.author.create_dm() recipient = ctx.get_human(user=user) human = ctx.get_human() mail = Mail(recipient=recipient, sender=sender, read=False) await mail.editor_for(ctx, "message") await mail.editor_for(ctx, "gold", min=0, max=human.gold, skippable=True) waiter = ItemWaiter(ctx, prompt=ctx.translate("mail_item_prompt"), skippable=True) try: mail.item = await waiter.wait() except Skipped: pass if mail.item is not None: human_item, _ = HumanItem.get_or_create(item=mail.item, human=human) if human_item.amount < 1: raise SendableException(ctx.translate("item_not_found")) human_item.amount -= 1 human_item.save() mail.residence = human.country mail.destination = recipient.country mail.end_date = mail.start_date + datetime.timedelta( minutes=mail.calculate_duration()) human.gold -= mail.gold or 0 sender.status = Pigeon.Status.mailing mail.save() human.save() sender.save() remind_emoji = "❗" embed = self.get_base_embed(ctx.guild) embed.description = f"Okay. Your pigeon is off to send a package to {recipient.mention}!" embed.set_footer( text= f"React with {remind_emoji} to get reminded when available.\n'{ctx.prefix}pigeon retrieve' to check on your pigeon" ) message = await ctx.send(embed=embed) waiter = ReactionWaiter(ctx, message, emojis=(remind_emoji, ), members=(ctx.author, )) await waiter.add_reactions() emoji = await waiter.wait(remove=True) if emoji is not None: Reminder.create(user_id=ctx.author.id, channel_id=ctx.channel.id, text=ctx.translate("pigeon_ready_to_be_retrieved"), due_date=mail.end_date) asyncio.gather(ctx.success(ctx.translate("reminder_created")))
def test_does_not_return_reminder_when_is_finished_is_false_and_it_is_not_due( self, reminder, time ): with freeze_time(time): assert Reminder.due_now().count() == 0
def test_does_not_return_finished_reminders(self, reminder): reminder.finish() assert Reminder.due_now().count() == 0