Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cachyos/Scripts/WIP/emu/cia_3ds_decryptor.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def parse_ctrtool_output(text: str) -> TitleInfo:
for line in text.splitlines():
if not info.title_id and (m := TITLE_ID_RE.search(line)):
info.title_id = m.group(1)
if not info.title_version and (m := TITLE_VERSION_RE.search(line)):
if (m := TITLE_VERSION_RE.search(line)):
info.title_version = m.group(1)
if not info.crypto_key and "Crypto Key" in line:
info.crypto_key = line.strip()
Expand All @@ -172,7 +172,7 @@ def parse_twl_ctrtool_output(text: str) -> TitleInfo:
for line in text.splitlines():
if not info.title_id and (m := TWL_TITLE_ID_RE.search(line)):
info.title_id = m.group(1)
if not info.title_version and (m := TITLE_VERSION_RE.search(line)):
if (m := TITLE_VERSION_RE.search(line)):
info.title_version = m.group(1)
if not info.crypto_key and (m := TWL_ENCRYPTED_RE.search(line)):
info.crypto_key = m.group(1)
Expand Down
61 changes: 61 additions & 0 deletions Cachyos/Scripts/WIP/emu/test_decryptor_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
import importlib.util
import unittest
import sys
from pathlib import Path

# Dynamically import cia_3ds_decryptor.py
file_path = Path(__file__).parent / "cia_3ds_decryptor.py"
spec = importlib.util.spec_from_file_location("cia_3ds_decryptor", str(file_path))
if spec is None:
raise ImportError(f"Could not load {file_path}")
decryptor = importlib.util.module_from_spec(spec)
sys.modules["cia_3ds_decryptor"] = decryptor
spec.loader.exec_module(decryptor)

Check warning on line 14 in Cachyos/Scripts/WIP/emu/test_decryptor_parser.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Cachyos/Scripts/WIP/emu/test_decryptor_parser.py#L14

Item "None" of "Loader | None" has no attribute "exec_module". (union-attr)
Comment on lines +7 to +14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This dynamic import logic is duplicated in test_decryptor_counters.py. To improve maintainability and reduce code duplication, consider refactoring this logic into a shared test helper function. For example, you could create a test_helper.py with a function that handles the module loading, which both test files can then import and use.


class TestParser(unittest.TestCase):
def test_parse_ctrtool_output_full(self):
text = """
Title id: 0004000000000100
TitleVersion: 10
Crypto Key: Secure
"""
info = decryptor.parse_ctrtool_output(text)
self.assertEqual(info.title_id, "0004000000000100")
self.assertEqual(info.title_version, "10")
self.assertEqual(info.crypto_key, "Crypto Key: Secure")

def test_parse_ctrtool_output_partial(self):

Check notice on line 28 in Cachyos/Scripts/WIP/emu/test_decryptor_parser.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Cachyos/Scripts/WIP/emu/test_decryptor_parser.py#L28

Method name "test_parse_ctrtool_output_partial" doesn't conform to '[a-z_][a-z0-9_]{2,30}$' pattern
text = "Title id: 0004000000000100"
info = decryptor.parse_ctrtool_output(text)
self.assertEqual(info.title_id, "0004000000000100")
self.assertEqual(info.title_version, "0")
self.assertEqual(info.crypto_key, "")

def test_parse_ctrtool_output_empty(self):
info = decryptor.parse_ctrtool_output("")
self.assertEqual(info.title_id, "")
self.assertEqual(info.title_version, "0")
self.assertEqual(info.crypto_key, "")

def test_parse_twl_ctrtool_output_full(self):

Check notice on line 41 in Cachyos/Scripts/WIP/emu/test_decryptor_parser.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Cachyos/Scripts/WIP/emu/test_decryptor_parser.py#L41

Method name "test_parse_twl_ctrtool_output_full" doesn't conform to '[a-z_][a-z0-9_]{2,30}$' pattern
text = """
TitleId: 0004800000000100
TitleVersion: 5
Encrypted: YES
"""
info = decryptor.parse_twl_ctrtool_output(text)
self.assertEqual(info.title_id, "0004800000000100")
self.assertEqual(info.title_version, "5")
self.assertEqual(info.crypto_key, "YES")

def test_sanitize_filename(self):
self.assertEqual(decryptor.sanitize_filename("Game Name (USA)!?.cia"), "Game Name USA.cia")
self.assertEqual(decryptor.sanitize_filename("valid_name-123.3ds"), "valid_name-123.3ds")
# Test that it preserves case (if TRANSLATE_TABLE is correct)
self.assertEqual(decryptor.sanitize_filename("UPPERCASE.CIA"), "UPPERCASE.CIA")
# If all characters are invalid, it returns the original string
self.assertEqual(decryptor.sanitize_filename("!!!"), "!!!")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To ensure the bug fix for title_version parsing is robustly tested, it's a good practice to add a test case that explicitly covers the fixed behavior. The current tests don't cover the scenario where multiple TitleVersion lines are present in the input. Adding a test for this will verify that the parser correctly captures the last value, as intended by the fix.

Suggested change
self.assertEqual(decryptor.sanitize_filename("!!!"), "!!!")
self.assertEqual(decryptor.sanitize_filename("!!!"), "!!!")
def test_version_parsing_uses_last_value(self):
text_with_multiple_versions = """
Title id: 0004000000000100
TitleVersion: 1
TitleVersion: 10
Crypto Key: Secure
"""
# Test standard parser
info = decryptor.parse_ctrtool_output(text_with_multiple_versions)
self.assertEqual(info.title_version, "10")
# Test TWL parser
info_twl = decryptor.parse_twl_ctrtool_output(text_with_multiple_versions)
self.assertEqual(info_twl.title_version, "10")


if __name__ == '__main__':

Check notice on line 60 in Cachyos/Scripts/WIP/emu/test_decryptor_parser.py

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

Cachyos/Scripts/WIP/emu/test_decryptor_parser.py#L60

expected 2 blank lines after class or function definition, found 1 (E305)
unittest.main()
Comment on lines +17 to +61
Loading