-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathtest_unit.py
156 lines (123 loc) · 4.87 KB
/
test_unit.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import asyncio
import logging
import os
import pathlib
from importlib import reload
import pytest
import pytest_asyncio
# Prevent Utils from importing dev_secrets by default
os.environ["ENV"] = "test"
from forest import utils, core
from forest.core import Message, Response
from tests.mockbot import MockBot
# Sample bot number alice
BOT_NUMBER = "+11111111111"
USER_NUMBER = "+22222222222"
def test_secrets(tmp_path: pathlib.Path) -> None:
"""Tests that utils.get_secret reads the values of dev_secrets properly"""
open(tmp_path / "test_secrets", "w", encoding="utf-8").write("A=B\nC=D")
os.chdir(tmp_path)
reload(utils)
assert utils.get_secret("A") == "B"
assert utils.get_secret("C") == "D"
assert utils.get_secret("E") == ""
def test_root(tmp_path: pathlib.Path) -> None:
"""Tests the Root Dir Logic"""
os.chdir(tmp_path)
# Test that ROOT_DIR is . when running locally
assert reload(utils).ROOT_DIR == "."
# Test that when Download is set to 1 and so downloading datastore from postgress,
# the Root Dir is /tmp/local-signal
open(tmp_path / "test_secrets", "w", encoding="utf-8").write("DOWNLOAD=1")
assert reload(utils).ROOT_DIR == "/tmp/local-signal"
# Tests that when a Fly App Name is specified, therefore it must be running on fly,
# the Root Dir is /app
os.environ["FLY_APP_NAME"] = "A"
assert reload(utils).ROOT_DIR == "/app"
# https://github.com/pytest-dev/pytest-asyncio/issues/68
# all async tests and fixtures implicitly use event_loop, which has scope "function" by default
# so if we want bot to have scope "session" (so it's not destroyed and created between tests),
# all the fixtures it uses need to have at least "session" scope
@pytest.fixture()
def event_loop(request):
"""Fixture version of the event loop"""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest_asyncio.fixture()
async def bot():
"""Bot Fixture allows for exiting gracefully"""
bot = MockBot(BOT_NUMBER)
yield bot
bot.sigints += 1
bot.exiting = True
bot.handle_messages_task.cancel()
await bot.client_session.close()
await core.pghelp.pool.close()
@pytest.mark.asyncio
async def test_commands(bot) -> None:
"""Tests commands"""
# Enable Magic allows for mistyped commands
os.environ["ENABLE_MAGIC"] = "1"
# Tests do_ping with a mistyped command, expecting "/pong foo"
assert await bot.get_cmd_output("/pingg foo") == "/pong foo"
# tests the uptime command just checks to see if it starts with "Uptime: "
assert (await bot.get_cmd_output("uptime")).startswith("Uptime: ")
# tests that eval only works for admins
assert (
await bot.get_cmd_output("/eval 1+1")
) == "you must be an admin to use this command"
print(await bot.get_cmd_output("/help"))
assert (await bot.get_cmd_output("/help")).startswith("Documented commands:")
# test the default behaviour
assert (await bot.get_cmd_output("gibberish two")).startswith(
"That didn't look like a valid command"
)
@pytest.mark.asyncio
async def test_questions(bot) -> None:
"""Tests the various questions from questionbot class"""
# Enable Magic allows for mistyped commands
os.environ["ENABLE_MAGIC"] = "1"
# the issue here is that we need to send "yes" *after* the question has been asked
# so we make it as create_task, then send the input, then await the task to get the result
answer = asyncio.create_task(
bot.ask_yesno_question(USER_NUMBER, "Do you like faeries?")
)
await bot.send_input("yes")
assert await answer is True
answer = asyncio.create_task(
bot.ask_freeform_question(USER_NUMBER, "What's your favourite tree?")
)
await bot.send_input("Birch")
assert await answer == "Birch"
answer = asyncio.create_task(
bot.ask_intable_question(USER_NUMBER, "How many fingers am I holding up?")
)
await bot.send_input("7")
assert await answer == 7
answer = asyncio.create_task(
bot.ask_floatable_question(USER_NUMBER, "How much is your life worth stranger?")
)
await bot.send_input("7.99")
assert await answer == 7.99
answer = asyncio.create_task(
bot.ask_freeform_question(USER_NUMBER, "What's your favourite tree?")
)
question_text = "What is your tshirt size?"
options = {"S": "", "M": "", "L": "", "XL": "", "XXL": ""}
choice = asyncio.create_task(
bot.ask_multiple_choice_question(
USER_NUMBER, question_text, options, require_confirmation=False
)
)
await bot.send_input("M")
assert await choice == "M"
choice = asyncio.create_task(
bot.ask_multiple_choice_question(
USER_NUMBER, question_text, options, require_confirmation=True
)
)
await bot.send_input("XXL")
await asyncio.sleep(0)
await bot.send_input("yes")
assert await choice == "XXL"