Skip to content

Commit

Permalink
Add new tests and fix failing tests
Browse files Browse the repository at this point in the history
  • Loading branch information
orende committed Jul 3, 2023
1 parent 42308e9 commit 62b59b7
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 12 deletions.
18 changes: 9 additions & 9 deletions minigalaxy/ui/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ def __get_installed_games(self) -> List[Game]:
os.makedirs(library_dir, mode=0o755)
directories = os.listdir(library_dir)
games = []
game_categories_dict = read_game_categories_file()
game_categories_dict = read_game_categories_file(CATEGORIES_FILE_PATH)
for directory in directories:
full_path = os.path.join(self.config.install_dir, directory)
# Only scan directories
Expand Down Expand Up @@ -184,7 +184,7 @@ def __add_games_from_api(self):
self.games[self.games.index(game)].category = game.category
if len(game.category) > 0: # exclude games without set category
game_category_dict[game.name] = game.category
update_game_categories_file(game_category_dict)
update_game_categories_file(game_category_dict, CATEGORIES_FILE_PATH)


def get_installed_windows_games(full_path, game_categories_dict=None):
Expand All @@ -205,24 +205,24 @@ def get_installed_windows_games(full_path, game_categories_dict=None):
return games


def update_game_categories_file(game_category_dict):
def update_game_categories_file(game_category_dict, categories_file_path):
if len(game_category_dict) == 0:
return
if not os.path.exists(CATEGORIES_FILE_PATH): # if file does not exist, create it and write dict
with open(CATEGORIES_FILE_PATH, 'wt') as fd:
if not os.path.exists(categories_file_path): # if file does not exist, create it and write dict
with open(categories_file_path, 'wt') as fd:
json.dump(game_category_dict, fd)
else:
with open(CATEGORIES_FILE_PATH, 'r+t') as fd: # if file exists, write dict only if not equal to file data
with open(categories_file_path, 'r+t') as fd: # if file exists, write dict only if not equal to file data
cached_game_category_dict = json.load(fd)
if game_category_dict != cached_game_category_dict:
fd.seek(os.SEEK_SET)
fd.truncate(0)
json.dump(game_category_dict, fd)


def read_game_categories_file():
def read_game_categories_file(categories_file_path):
cached_game_category_dict = {}
if os.path.exists(CATEGORIES_FILE_PATH):
with open(CATEGORIES_FILE_PATH, 'rt') as fd:
if os.path.exists(categories_file_path):
with open(categories_file_path, 'rt') as fd:
cached_game_category_dict = json.load(fd)
return cached_game_category_dict
4 changes: 2 additions & 2 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
API_GET_INFO_STELLARIS = [{'id': '51622789000874509', 'game_id': '51154268886064420', 'platform_id': 'gog', 'external_id': '1508702879', 'game': {'genres': [{'id': '51071904337940794', 'name': {'*': 'Strategy', 'en-US': 'Strategy'}, 'slug': 'strategy'}], 'summary': {'*': 'Stellaris description'}, 'visible_in_library': True, 'aggregated_rating': 78.5455, 'game_modes': [{'id': '53051895165351137', 'name': 'Single player', 'slug': 'single-player'}, {'id': '53051908711988230', 'name': 'Multiplayer', 'slug': 'multiplayer'}], 'horizontal_artwork': {'url_format': 'https://images.gog.com/742acfb77ec51ca48c9f96947bf1fc0ad8f0551c9c9f338021e8baa4f08e449f{formatter}.{ext}?namespace=gamesdb'}, 'background': {'url_format': 'https://images.gog.com/742acfb77ec51ca48c9f96947bf1fc0ad8f0551c9c9f338021e8baa4f08e449f{formatter}.{ext}?namespace=gamesdb'}, 'vertical_cover': {'url_format': 'https://images.gog.com/8d822a05746670fb2540e9c136f0efaed6a2d5ab698a9f8bd7f899d21f2022d2{formatter}.{ext}?namespace=gamesdb'}, 'cover': {'url_format': 'https://images.gog.com/8d822a05746670fb2540e9c136f0efaed6a2d5ab698a9f8bd7f899d21f2022d2{formatter}.{ext}?namespace=gamesdb'}, 'logo': {'url_format': 'https://images.gog.com/c50a5d26c42d84b4b884976fb89d10bb3e97ebda0c0450285d92b8c50844d788{formatter}.{ext}?namespace=gamesdb'}, 'icon': {'url_format': 'https://images.gog.com/c85cf82e6019dd52fcdf1c81d17687dd52807835f16aa938abd2a34e5d9b99d0{formatter}.{ext}?namespace=gamesdb'}, 'square_icon': {'url_format': 'https://images.gog.com/c3adc81bf37f1dd89c9da74c13967a08b9fd031af4331750dbc65ab0243493c8{formatter}.{ext}?namespace=gamesdb'}}}]
GAMESDB_INFO_STELLARIS = {'cover': 'https://images.gog.com/8d822a05746670fb2540e9c136f0efaed6a2d5ab698a9f8bd7f899d21f2022d2.png?namespace=gamesdb', 'vertical_cover': 'https://images.gog.com/8d822a05746670fb2540e9c136f0efaed6a2d5ab698a9f8bd7f899d21f2022d2.png?namespace=gamesdb', 'background': 'https://images.gog.com/742acfb77ec51ca48c9f96947bf1fc0ad8f0551c9c9f338021e8baa4f08e449f.png?namespace=gamesdb', 'summary': {'*': 'Stellaris description'}, 'genre': {'*': 'Strategy', 'en-US': 'Strategy'}}
API_GET_INFO_BLACKWELL = [{'id': '51437500425760439', 'game_id': '51295394952128810', 'platform_id': 'gog', 'external_id': '1207662883', 'dlcs_ids': [], 'dlcs': [], 'parent_id': None, 'supported_operating_systems': [{'slug': 'linux', 'name': 'Linux'}, {'slug': 'osx', 'name': 'macOS'}, {'slug': 'windows', 'name': 'Windows'}], 'available_languages': [{'code': 'en-US'}], 'first_release_date': '2006-12-23T00:00:00+0000', 'game': {'id': '51295394952128810', 'parent_id': None, 'dlcs_ids': [], 'first_release_date': '2006-12-23T00:00:00+0000', 'releases': [{'id': '51295394972780958', 'platform_id': 'steam', 'external_id': '80330', 'release_per_platform_id': 'steam_80330'}, {'id': '51437500425760439', 'platform_id': 'gog', 'external_id': '1207662883', 'release_per_platform_id': 'gog_1207662883'}, {'id': '52472176412391232', 'platform_id': 'humble', 'external_id': 'theblackwelllegacy', 'release_per_platform_id': 'humble_theblackwelllegacy'}, {'id': '52990950679797056', 'platform_id': 'humble', 'external_id': 'blackwelllegacy_steam', 'release_per_platform_id': 'humble_blackwelllegacy_steam'}, {'id': '54824915113880126', 'platform_id': 'amiga', 'external_id': 'blackwell1', 'release_per_platform_id': 'amiga_blackwell1'}, {'id': '56154123001776496', 'platform_id': 'humble', 'external_id': 'blackwelllegacy_bundle_steam', 'release_per_platform_id': 'humble_blackwelllegacy_bundle_steam'}, {'id': '51295394952128810', 'platform_id': 'generic', 'external_id': '51295394952128810', 'release_per_platform_id': 'generic_51295394952128810'}], 'title': {'*': 'The Blackwell Legacy', 'en-US': 'The Blackwell Legacy'}, 'sorting_title': {'*': 'Blackwell Legacy', 'en-US': 'Blackwell Legacy'}, 'type': 'game', 'developers_ids': ['51141380061810434'], 'developers': [{'id': '51141380061810434', 'name': 'Wadjet Eye Games', 'slug': 'wadjet-eye-games'}], 'publishers_ids': ['51141380061810434'], 'publishers': [{'id': '51141380061810434', 'name': 'Wadjet Eye Games', 'slug': 'wadjet-eye-games'}], 'genres_ids': ['51071842251704278', '51121492616405278', '51141224673762034', '51141224986801358'], 'genres': [{'id': '51071842251704278', 'name': {'*': 'Adventure', 'en-US': 'Adventure'}, 'slug': 'adventure'}, {'id': '51121492616405278', 'name': {'*': 'Indie', 'en-US': 'Indie'}, 'slug': 'indie'}, {'id': '51141224673762034', 'name': {'*': 'Puzzle', 'en-US': 'Puzzle'}, 'slug': 'puzzle'}, {'id': '51141224986801358', 'name': {'*': 'Point-and-click', 'en-US': 'Point-and-click'}, 'slug': 'point-and-click'}], 'themes_ids': ['51141224799400616', '51141227696328058', '51141227910729860'], 'themes': [{'id': '51141224799400616', 'name': {'*': 'Comedy', 'en-US': 'Comedy'}, 'slug': 'comedy'}, {'id': '51141227696328058', 'name': {'*': 'Mystery', 'en-US': 'Mystery'}, 'slug': 'mystery'}, {'id': '51141227910729860', 'name': {'*': 'Drama', 'en-US': 'Drama'}, 'slug': 'drama'}], 'screenshots': [{'url_format': 'https://images.gog.com/368f07e0edcce9191e60a004b0ef7bf8d9a97eac65b66e5e497f9e2728045255{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/075326e70912449e02c3d4593a26317ad8d7f8ba5f2d0d3aa216a5a467130f34{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/2c71a940d797c466a563ecfc132933300ce37bd996140dbaaf48333d2f628fb3{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/d8c490c12f0534adeb69fdeb467a4719d24765a85a58a880f9aab13008d14683{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/5724fb0d43b4b753e89a6dec52b40a8c401396d6b5ecaa228115a3b06c5fd374{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/7478e2b53e403ee04eb27331ecebad0d6e3403e76c747fffd6f5b2303005b174{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/bd6f6ba043f9ae0883c196086841891ac5ed11dcf933ab2ca3f104312be10802{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/c37db76ad0d3f6471a5bbac1cc5a17393ee5a2c8ae16150cc221aac5855dd788{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/9ec05f3b79a0e3bd9a2b4eb29788222b5723feb6273b6a0bbb711d53d6a93b25{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/7376efd38b2aa383e16d066c6cfbc78fefa9b870f91033666a08bef85bac6db9{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/78145ccd85eca1fec952a464b3b9aeea7b5288518282e8194e3a0991fd9aef77{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/d46d89dfabe116db2f428138d3a3481faf91e00759ef97e02645da8f2652df3a{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/01e93965ea0ce72fdb50472e08a11924a9c5aa45f86a6aed4deeff987010df34{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/c2f064852161738df48918111327c108cdb014bffff487caa13caa2f7c2d5750{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/5cedd80d5f46fa20d4f95e9b8305d608b44c098b4741d2347e0365c2c9932cda{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/b80f003398c1d4e63ae2054665ee90785a9ea526b371859269e92c51ac7840c1{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/702fe48f311ef0d398e219cf28eda78b64bf3104dda937983b7ec621d0845caa{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/73b9adb70ec1c2bfc75cd6286a4b1f5c81959a4e25ce4e0527dd9a61d28c7953{formatter}.{ext}?namespace=gamesdb'}], 'videos': [{'provider': 'youtube', 'video_id': 'j026WKDQhi8', 'thumbnail_id': 'j026WKDQhi8', 'name': 'Trailer'}], 'artworks': [{'url_format': 'https://images.gog.com/19eba3c8303ce3cdb45cc9f2f94993efd2620f7f12eeac814512e64d26e88f0f{formatter}.{ext}?namespace=gamesdb'}, {'url_format': 'https://images.gog.com/978a934689c303511c425450c62db88edd11ac4da9026d801159decf605cd93e{formatter}.{ext}?namespace=gamesdb'}], 'summary': {'*': "omitted for test", 'en-US': "omitted for test"}, 'visible_in_library': True, 'aggregated_rating': 70, 'game_modes': [{'id': '53051895165351137', 'name': 'Single player', 'slug': 'single-player'}], 'horizontal_artwork': {'url_format': 'https://images.gog.com/e6e6d9001ec0c990327bd8f20630b5e39d0b5d33f69778163025d9d7b04f3c44{formatter}.{ext}?namespace=gamesdb'}, 'background': {'url_format': 'https://images.gog.com/e6e6d9001ec0c990327bd8f20630b5e39d0b5d33f69778163025d9d7b04f3c44{formatter}.{ext}?namespace=gamesdb'}, 'vertical_cover': {'url_format': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61{formatter}.{ext}?namespace=gamesdb'}, 'cover': {'url_format': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61{formatter}.{ext}?namespace=gamesdb'}, 'logo': {'url_format': 'https://images.gog.com/a82f4f793fc7e981b7a8d429508b11ba7ec5783f3ae5db6a8d3508bd139ba122{formatter}.{ext}?namespace=gamesdb'}, 'square_icon': {'url_format': 'https://images.gog.com/978a934689c303511c425450c62db88edd11ac4da9026d801159decf605cd93e{formatter}.{ext}?namespace=gamesdb'}, 'global_popularity_all_time': 0, 'global_popularity_current': 0, 'series': {'id': '53060497266141230', 'name': 'Blackwell', 'slug': 'blackwell'}}, 'title': {'*': 'Blackwell Legacy', 'en-US': 'The Blackwell Legacy'}, 'sorting_title': {'*': 'Blackwell Legacy', 'en-US': 'Blackwell Legacy'}, 'type': 'game', 'summary': {'*': "When Rosa Blackwell's only relative dies after twenty years in a coma, she thinks the worst is over. This all changes when Joey Mallone, a sardonic ghost from the 1930s, blows into her life and tells her that she is a medium. Whether they like it or not, it is up to them to cure the supernatural ills of New York in this critically-acclaimed series of point-and-click adventure games. \r\nWhen three NYU students kill themselves one after the other, nobody thinks that a sinister force is at work. Nobody but fledgling medium Rosa Blackwell and her new spirit guide Joey Mallone. It's trial by fire as they set these troubled spirits to rest.", 'en-US': "When Rosa Blackwell's only relative dies after twenty years in a coma, she thinks the worst is over. This all changes when Joey Mallone, a sardonic ghost from the 1930s, blows into her life and tells her that she is a medium. Whether they like it or not, it is up to them to cure the supernatural ills of New York in this critically-acclaimed series of point-and-click adventure games.\nWhen three NYU students kill themselves one after the other, nobody thinks that a sinister force is at work. Nobody but fledgling medium Rosa Blackwell and her new spirit guide Joey Mallone. It's trial by fire as they set these troubled spirits to rest."}, 'videos': [{'provider': 'youtube', 'video_id': 'vkinYRD5sr4', 'thumbnail_id': 'vkinYRD5sr4', 'name': None}, {'provider': 'youtube', 'video_id': 'gLcoCPfc1zE', 'thumbnail_id': 'gLcoCPfc1zE', 'name': None}], 'game_modes': [{'id': '53051895165351137', 'name': 'Single player', 'slug': 'single-player'}], 'logo': {'url_format': 'https://images.gog.com/a82f4f793fc7e981b7a8d429508b11ba7ec5783f3ae5db6a8d3508bd139ba122{formatter}.{ext}?namespace=gamesdb'}, 'series': {'id': '53060497266141230', 'name': 'Blackwell', 'slug': 'blackwell'}}]
GAMESDB_INFO_BLACKWELL = {'background': 'https://images.gog.com/e6e6d9001ec0c990327bd8f20630b5e39d0b5d33f69778163025d9d7b04f3c44.png?namespace=gamesdb','cover': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61.png?namespace=gamesdb','genre': {'*': 'Adventure, Indie, Puzzle, Point-and-click', 'en-US': 'Adventure, Indie, Puzzle, Point-and-click'},'summary': {'*': 'omitted for test', 'en-US': 'omitted for test'},'vertical_cover': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61.png?namespace=gamesdb'}
GAMESDB_INFO_BLACKWELL = {'background': 'https://images.gog.com/e6e6d9001ec0c990327bd8f20630b5e39d0b5d33f69778163025d9d7b04f3c44.png?namespace=gamesdb', 'cover': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61.png?namespace=gamesdb', 'genre': {'*': 'Adventure, Indie, Puzzle, Point-and-click', 'en-US': 'Adventure, Indie, Puzzle, Point-and-click'}, 'summary': {'*': 'omitted for test', 'en-US': 'omitted for test'}, 'vertical_cover': 'https://images.gog.com/87f87afa3a55ca5eb59df9a66c5063c202281432262b3f0fe8ef8e324270df61.png?namespace=gamesdb'}


class TestApi(TestCase):
Expand Down Expand Up @@ -113,7 +113,7 @@ def test1_get_library(self):
config = MagicMock()
api = Api(config, session)
api.active_token = True
response_dict = {'totalPages': 1, 'products': [{'id': 1097893768, 'title': 'Neverwinter Nights: Enhanced Edition', 'image': '//images-2.gog-statics.com/8706f7fb87a4a41bc34254f3b49f59f96cf13d067b2c8bbfd8d41c327392052a', 'url': '/game/neverwinter_nights_enhanced_edition_pack', 'worksOn': {'Windows': True, 'Mac': True, 'Linux': True}}]}
response_dict = {'totalPages': 1, 'products': [{'id': 1097893768, 'title': 'Neverwinter Nights: Enhanced Edition', 'image': '//images-2.gog-statics.com/8706f7fb87a4a41bc34254f3b49f59f96cf13d067b2c8bbfd8d41c327392052a', 'url': '/game/neverwinter_nights_enhanced_edition_pack', 'worksOn': {'Windows': True, 'Mac': True, 'Linux': True}, "category": "Role-playing"}]}
api.active_token_expiration_time = time.time() + 10.0
response_mock = MagicMock()
response_mock.json.return_value = response_dict
Expand Down
62 changes: 61 additions & 1 deletion tests/test_ui_library.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import json
import os
import sys
import uuid
from unittest import TestCase, mock
from unittest.mock import MagicMock, patch, mock_open
import tempfile

m_gtk = MagicMock()
m_gi = MagicMock()
m_window = MagicMock()
m_preferences = MagicMock()
m_gametile = MagicMock()
m_gametilelist = MagicMock()
m_categoryfilters = MagicMock()


class UnitTestGtkTemplate:
Expand Down Expand Up @@ -56,8 +61,10 @@ class Notify:
sys.modules['minigalaxy.ui.preferences'] = m_preferences
sys.modules['minigalaxy.ui.gametile'] = m_gametile
sys.modules['minigalaxy.ui.gametilelist'] = m_gametilelist
sys.modules['minigalaxy.ui.categoryfilters'] = m_categoryfilters
from minigalaxy.game import Game # noqa: E402
from minigalaxy.ui.library import Library, get_installed_windows_games # noqa: E402
from minigalaxy.ui.library import Library, get_installed_windows_games, read_game_categories_file, \
update_game_categories_file # noqa: E402

SELF_GAMES = {"Neverwinter Nights: Enhanced Edition": "1097893768", "Beneath A Steel Sky": "1207658695",
"Stellaris (English)": "1508702879"}
Expand Down Expand Up @@ -204,10 +211,63 @@ def test2_get_installed_windows_game(self, mock_listdir):
obs = games[0].name
self.assertEqual(exp, obs)

def test_read_game_categories_file_should_return_populated_dict(self):
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as tmpfile:
tmpfile.write('{"Test Game":"Adventure"}')
tmpfile.flush()

actual = read_game_categories_file(tmpfile.name)

self.assertTrue(len(actual))
self.assertEqual(actual, {'Test Game': 'Adventure'})

@mock.patch('os.path.exists')
def test_update_game_categories_file_should_skip_for_empty_dict(self, mock_path_exists: MagicMock):
mock_path_exists.side_effect = Exception("Test error")

update_game_categories_file({}, None)

self.assertFalse(mock_path_exists.called)

def test_update_game_categories_file_should_create_file_if_not_found(self):
initially_non_existent_file = f'/tmp/{uuid.uuid4()}.json'
self.assertFalse(os.path.exists(initially_non_existent_file))
expected = {'Test game': 'Adventure'}

update_game_categories_file(expected, initially_non_existent_file)

self.assertTrue(os.path.exists(initially_non_existent_file))
self.assertDictEqual(expected, read_game_categories_file(initially_non_existent_file))

def test_update_game_categories_file_should_skip_if_file_found_with_identical_contents(self):
expected = {"Test Game": "Adventure"}
with tempfile.NamedTemporaryFile(mode='r+t', delete=False) as tmpfile:
json.dump(expected, tmpfile)
tmpfile.flush()

update_game_categories_file(expected, tmpfile.name)

tmpfile.seek(os.SEEK_SET)
actual = json.load(tmpfile)
self.assertDictEqual(actual, expected)

def test_update_game_categories_file_should_overwrite_file_if_contents_differ(self):
with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as tmpfile:
tmpfile.write('{"Test Game":"Adventure"}')
tmpfile.flush()
expected = {"Test Game": "Adventure", "Another Game": "Strategy"}

update_game_categories_file(expected, tmpfile.name)

tmpfile.seek(os.SEEK_SET)
actual = json.load(tmpfile)
self.assertDictEqual(actual, expected)


del sys.modules['gi']
del sys.modules['gi.repository']
del sys.modules['minigalaxy.ui.window']
del sys.modules['minigalaxy.ui.preferences']
del sys.modules['minigalaxy.ui.gametile']
del sys.modules['minigalaxy.ui.gametilelist']
del sys.modules['minigalaxy.ui.categoryfilters']
2 changes: 2 additions & 0 deletions tests/test_ui_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
m_preferences = MagicMock()
m_login = MagicMock()
m_about = MagicMock()
m_categoryfilters = MagicMock()


class UnitTestGtkTemplate:
Expand Down Expand Up @@ -56,6 +57,7 @@ def __init__(self, title):
sys.modules['minigalaxy.ui.login'] = m_login
sys.modules['minigalaxy.ui.about'] = m_about
sys.modules['minigalaxy.ui.gtk'] = u_gi_repository
sys.modules['minigalaxy.ui.categoryfilters'] = m_categoryfilters
from minigalaxy.ui.window import Window # noqa: E402


Expand Down

0 comments on commit 62b59b7

Please sign in to comment.