Skip to content

Commit

Permalink
[+] add autotests for clans fastapi functions, add member ranking, ad…
Browse files Browse the repository at this point in the history
…d Belarusian translation
  • Loading branch information
rotlir committed Jun 24, 2024
1 parent 4fae1eb commit f69cc2d
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 39 deletions.
15 changes: 12 additions & 3 deletions galaxy_backend/api/clans.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ async def get_owner(clan_id: int) -> int:
return clan_owner_user.tg_id


def sort_members(member: User) -> int:
return member.coins

# now it always returns a list of users sorted by the amount of their coins
async def get_members(clan_id: int) -> list[User]:
return await User.filter(clan_id=clan_id)
users = await User.filter(clan_id=clan_id)
users.sort(key=sort_members)
return users


# get an invite link for a clan with id clan_id
Expand All @@ -88,20 +94,23 @@ async def get_invite_link(clan_id: int):
raise fastapi.HTTPException(status_code=400, detail=str(e))


# list all clans registered in the db
# returns something like
# {'clan2': {'id': 2, 'name': 'ClanA'}, 'clan3': {'id': 3, 'name': 'ClanB'}, 'clan4': {'id': 4, 'name': 'ClanC'}}
@api.routers.clan.get('/list')
async def list_clans():
try:
clans = await Clan.all()
clans_dict = {}
clan_dict = {
'id': 0,
'name': ''
}
clans_dict = {}
for clan in clans:
assert isinstance(clan, Clan)
clan_dict['id'] = clan.id
clan_dict['name'] = clan.name
clans_dict[f'clan{clan.id}'] = clan_dict
clans_dict[f'clan{clan.id}'] = clan_dict.copy()
return clans_dict
except Exception as e:
raise fastapi.HTTPException(status_code=400, detail=str(e))
Expand Down
23 changes: 23 additions & 0 deletions galaxy_backend/langs/be.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"start_game": "Пачаць гульню",
"bonuses": "Бонусы",
"back": "Назад",
"join": "Далучыцца",
"check": "Праверыць",
"join_our_channel": "Падпіска на канал",
"hello": "Прывітанне",
"coins_for_tasks": "Вы атрымаеце манеты за выкананыя заданні. Выберыце заданне, якое хочаце выканаць, ніжэй.",
"click_to_join": "Націсніце кнопку ніжэй, каб далучыцца да канала",
"thanks_for_joining": "Дзякуем за падпіску на наш канал, вось вашыя 100 манет!",
"invite_friend_button": "Запрасіць сябра",
"clans_invalid_id": "На жаль, гэтая спасылка-запрашэнне несапраўдная. Папрасіце чалавека, які даў вам яе, даць іншую.",
"clans_already_participate": "Вы ўжо ў складзе гэтага клана.",
"yes": "Так",
"no": "Не",
"clan_join_request": "Вы былі запрошаны ў клан '{clan}'. Вы хочаце далучыцца да гэтага клана?",
"clan_join_confirmed": "Віншуем! Цяпер вы ўдзельнік клана '{clan}'!",
"clan_join_denied": "Вы адмовіліся далучацца да клана '{clan}'",
"not_subscribed": "Вы не падпісаныя",
"clan_already_owned": "Вы валодаеце кланам, таму не можаце далучыцца да іншага клана."
}

3 changes: 2 additions & 1 deletion galaxy_backend/langs/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"clan_join_request": "You were invited to the clan '{clan}'. Do you want to join this clan?",
"clan_join_confirmed": "Congratulations! You are a member of the clan '{clan}' now!",
"clan_join_denied": "You refused to join the clan '{clan}'",
"not_subscribed": "You are not subscribed"
"not_subscribed": "You are not subscribed",
"clan_already_owned": "You own a clan so you can't join an another clan."
}

3 changes: 2 additions & 1 deletion galaxy_backend/langs/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"clan_join_request": "Вы были приглашены в клан '{clan}'. Вы хотите присоединиться к этому клану?",
"clan_join_confirmed": "Поздравляем! Теперь вы участник клана '{clan}'!",
"clan_join_denied": "Вы отказались присоединяться к клану '{clan}'",
"not_subscribed": "Вы не подписаны"
"not_subscribed": "Вы не подписаны",
"clan_already_owned": "Вы владеете кланом, так что вы не можете присоединиться к другому клану."
}

3 changes: 2 additions & 1 deletion galaxy_backend/langs/uk.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"clan_join_request": "Вас запросили до клану '{clan}'. Чи хочете ви приєднатися до цього клану?",
"clan_join_confirmed": "Вітаємо! Ви тепер учасник клану '{clan}'!",
"clan_join_denied": "Ви відмовилися від приєднання до клану '{clan}'",
"not_subscribed": "Ви не підписані"
"not_subscribed": "Ви не підписані",
"clan_already_owned": "You own a clan so you can't join an another clan."
}

17 changes: 10 additions & 7 deletions galaxy_backend/tests/clans.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ async def check_basic() -> str:
except AssertionError:
raise AssertionError("remove_user() did not work correctly")
# cleanup for further tests
clanA_owner = await ClanOwner.get(clan=clanA)
await clanA_owner.delete()
await clanA.delete()
await user1.delete()
await user2.delete()
await user3.delete()
await user4.delete()
clan_owners = await ClanOwner.all()
for clan_owner in clan_owners:
await clan_owner.delete()
all_clans = await Clan.all()
for clan in all_clans:
await clan.delete()
users = await User.all()
for user in users:
if user.tg_id != 0:
await user.delete()
return "check basic functionality of clans"

146 changes: 120 additions & 26 deletions galaxy_backend/tests/clans_fastapi.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
from core.common import all
from core.common import all, tg
from models.db import User, Clan, ClanOwner
import api.clans

async def init():
user1 = await User.create(tg_id=1)
user2 = await User.create(tg_id=2)
user3 = await User.create(tg_id=3)
user4 = await User.create(tg_id=4)
user5 = await User.create(tg_id=5)
user6 = await User.create(tg_id=6)
user7 = await User.create(tg_id=7)
user8 = await User.create(tg_id=8)
user9 = await User.create(tg_id=9)
user1 = await User.create(tg_id=1, coins=100)
user2 = await User.create(tg_id=2, coins=200)
user3 = await User.create(tg_id=3, coins=300)
user4 = await User.create(tg_id=4, coins=400)
user5 = await User.create(tg_id=5, coins=500)
user6 = await User.create(tg_id=6, coins=600)
user7 = await User.create(tg_id=7, coins=700)
user8 = await User.create(tg_id=8, coins=800)
user9 = await User.create(tg_id=9, coins=900)
clanA = await api.clans.create_clan('ClanA', user1.tg_id)
clanB = await api.clans.create_clan('ClanB', user2.tg_id)
clanC = await api.clans.create_clan('ClanC', user3.tg_id)
await api.clans.add_user(user4.tg_id, clanA.id)
await api.clans.add_user(user5.tg_id, clanA.id)
await api.clans.add_user(user6.tg_id, clanB.id)
await api.clans.add_user(user7.tg_id, clanB.id)
await api.clans.add_user(user8.tg_id, clanC.id)
await api.clans.add_user(user9.tg_id, clanC.id)
await api.clans.add_user(clanA.id, user4.tg_id)
await api.clans.add_user(clanA.id, user5.tg_id)
await api.clans.add_user(clanB.id, user6.tg_id)
await api.clans.add_user(clanB.id, user7.tg_id)
await api.clans.add_user(clanC.id, user8.tg_id)
await api.clans.add_user(clanC.id, user9.tg_id)


async def deinit():
Expand All @@ -37,21 +37,115 @@ async def deinit():

async def run_tests() -> str:
await init()
list_clans_res = await list_clans()
if list_clans_res != 'success':
await deinit()
raise Exception(list_clans_res)
await list_clans()
clans = await Clan.all()
for clan in clans:
await get_invite(clan)
user4 = await User.filter(tg_id=4).first()
user6 = await User.filter(tg_id=6).first()
user8 = await User.filter(tg_id=8).first()
assert isinstance(user4, User)
assert isinstance(user6, User)
assert isinstance(user8, User)
clanA = await Clan.filter(name='ClanA').first()
clanB = await Clan.filter(name='ClanB').first()
clanC = await Clan.filter(name='ClanC').first()
assert isinstance(clanA, Clan)
assert isinstance(clanB, Clan)
assert isinstance(clanC, Clan)
await remove_user(user4)
await remove_user(user6)
await remove_user(user8)
await create_clan('ClanD', user4)
await get_owner(clanA)
await get_owner(clanB)
await get_owner(clanC)
await api.clans.add_user(clanA.id, user6.tg_id)
clanD = await Clan.filter(name='ClanD').first()
assert isinstance(clanD, Clan)
await get_members(clanA)
await get_members(clanB)
await get_members(clanD)
await deinit()
return list_clans_res
return 'check clans fastapi functions'


async def list_clans() -> str:
async def list_clans():
response = await all.async_client.get('/clan/list')
assert response.status_code == 200
data = response.json()
expected_result = {'clan2': {'id': 2, 'name': 'ClanA'}, 'clan3': {'id': 3, 'name': 'ClanB'}, 'clan4': {'id': 4, 'name': 'ClanC'}}
assert data == expected_result


async def get_invite(clan: Clan):
try:
assert response.status_code == 200
except AssertionError:
return 'list_clans(): response status code is not 200'
info = await tg.bot.get_me()
except AttributeError: # if run without token
return
username = info.username
expected_result = f'https://t.me/{username}?start=joinclan_{clan.id}'
response = await all.async_client.get(f'/clan/get_invite/{clan.id}')
assert response.status_code == 200
msg = response.json()
assert isinstance(msg, dict)
link = msg['link']
assert isinstance(link, str)
assert link == expected_result


async def remove_user(user: User):
await user.fetch_related('clan')
clan = user.clan
assert isinstance(clan, Clan)
members_expected = await api.clans.get_members(clan.id)
members_expected.remove(user)
id = user.tg_id
payload = {'user_id': id}
response = await all.async_client.post('/clan/member/remove', json=payload)
assert response.status_code == 200
data = response.json()
return data
expected_result = {'message': 'User removed from clan'}
assert data == expected_result
members_new = await api.clans.get_members(clan.id)
assert members_expected == members_new


async def create_clan(name: str, owner: User):
payload = {'clan_name': name, 'clan_owner_id': owner.tg_id}
response = await all.async_client.post('/clan/create', json=payload)
assert response.status_code == 200
msg = response.json()
clan_from_db = await Clan.filter(name=name).first()
assert isinstance(clan_from_db, Clan)
await api.clans.get_owner(clan_from_db.id)
response_expected = {'clan_id': clan_from_db.id, 'clan_name': name}
assert msg == response_expected


async def get_owner(clan: Clan):
response = await all.async_client.get(f'/clan/get_owner/{clan.id}')
assert response.status_code == 200
owner_from_db = await api.clans.get_owner(clan.id)
msg = response.json()
assert isinstance(msg, dict)
owner_id = msg['clan_owner_id']
assert isinstance(owner_id, int)
assert owner_id == owner_from_db


async def get_members(clan: Clan):
response = await all.async_client.get(f'/clan/member/list/{clan.id}')
assert response.status_code == 200
msg = response.json()
assert isinstance(msg, dict)
members_from_db = await api.clans.get_members(clan.id)
members_from_db_id = []
for member in members_from_db:
members_from_db_id.append(member.tg_id)
members = msg['members']
assert isinstance(members, list)
members.sort()
members_from_db_id.sort()
assert members == members_from_db_id

1 change: 1 addition & 0 deletions galaxy_backend/tests/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@


async def thread1():
# please don't change the order of the first 3 entries or tests may break
to_run_list: list[core.types.cor_str] = [
init.create_user,
clans.check_basic,
Expand Down
1 change: 1 addition & 0 deletions galaxy_backend/tg/parse_langs.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def load_langs(path: Path) -> dict:
langs['en'] = Lang(path / 'en.json')
langs['ru'] = Lang(path / 'ru.json', default_lang=langs['en'])
langs['uk'] = Lang(path / 'uk.json', default_lang=langs['en'])
langs['be'] = Lang(path / 'be.json', default_lang=langs['en'])
return langs

langs = load_langs(core.common.path.langs)
Expand Down

0 comments on commit f69cc2d

Please sign in to comment.