mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-09-22 23:08:08 +03:00
Fix cross-platform test assumptions
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -246,6 +246,12 @@ Linux, and macOS with Python 3.13 and PySide6 6.8.3. The publication workflow re
|
||||
that job before PyPI publication. Opt-in tests and packaged/manual smoke checks remain
|
||||
separate; local Windows results do not establish the other CI targets.
|
||||
|
||||
The settings harness compares canonical paths on every access so macOS temporary-directory
|
||||
aliases and Windows short names do not look like sandbox escapes. Its isolation regressions
|
||||
cover an aliased root and rejection of paths outside that root. The QR responsiveness test
|
||||
queues unrelated work after generation starts and requires delivery before completion;
|
||||
it does not assume a platform-specific order between zero-delay Qt timers.
|
||||
|
||||
The Home/Log workflow regressions exercise debounced typing, explicit submit/clear, navigation catch-up, focus-scoped
|
||||
Find/edit shortcuts, and live log filtering. These are real Qt tests in `test_qt_interactions.py` and
|
||||
`test_ui_behavior.py`; no production log source or profile network is started. The two optional pause regressions
|
||||
|
||||
+3
-1
@@ -108,7 +108,9 @@ def _initializeSettingsSandbox():
|
||||
global _settingsDirectory
|
||||
|
||||
if _settingsDirectory is not None:
|
||||
return Path(_settingsDirectory.name)
|
||||
# TemporaryDirectory may retain a macOS /var alias or Windows short
|
||||
# path. Match the canonical root used on initialization and by Qt.
|
||||
return Path(_settingsDirectory.name).resolve()
|
||||
|
||||
_settingsDirectory = tempfile.TemporaryDirectory(
|
||||
prefix='furious-tests-settings-root-'
|
||||
|
||||
@@ -26,6 +26,9 @@ from PySide6.QtTest import QTest
|
||||
from PySide6.QtWidgets import QPushButton, QVBoxLayout, QWidget
|
||||
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import tests.support as SupportModule
|
||||
|
||||
from tests.support import (
|
||||
application,
|
||||
@@ -58,7 +61,9 @@ class TestHarnessIsolationTest(unittest.TestCase):
|
||||
|
||||
assertIsolatedSettings(outer)
|
||||
|
||||
self.assertIn(settingsSandboxPath(), Path(outer.fileName()).parents)
|
||||
self.assertIn(
|
||||
settingsSandboxPath(), Path(outer.fileName()).resolve().parents
|
||||
)
|
||||
|
||||
with isolatedSettings() as inner:
|
||||
innerIdentity = (app.organizationName(), app.applicationName())
|
||||
@@ -87,7 +92,35 @@ class TestHarnessIsolationTest(unittest.TestCase):
|
||||
|
||||
assertIsolatedSettings(settings)
|
||||
|
||||
self.assertIn(settingsSandboxPath(), Path(settings.fileName()).parents)
|
||||
self.assertIn(
|
||||
settingsSandboxPath(), Path(settings.fileName()).resolve().parents
|
||||
)
|
||||
|
||||
def testExistingSandboxRootUsesTheSameCanonicalPath(self):
|
||||
"""Normalize reused temporary-directory aliases before containment checks."""
|
||||
root = settingsSandboxPath().resolve()
|
||||
alias = root / '..' / root.name
|
||||
|
||||
# TemporaryDirectory.name can retain an alias even though QSettings
|
||||
# returns the canonical path (macOS /var or Windows short user names).
|
||||
with mock.patch.object(SupportModule._settingsDirectory, 'name', str(alias)):
|
||||
self.assertEqual(settingsSandboxPath(), root)
|
||||
|
||||
with isolatedSettings() as settings:
|
||||
assertIsolatedSettings(settings)
|
||||
settings.setValue('alias-fixture', 'isolated')
|
||||
settings.sync()
|
||||
self.assertEqual(settings.value('alias-fixture'), 'isolated')
|
||||
|
||||
def testSettingsOutsideSandboxAreStillRejected(self):
|
||||
"""Reject a sibling path even when its name shares the sandbox prefix."""
|
||||
root = settingsSandboxPath().resolve()
|
||||
outside = root.with_name(root.name + '-outside') / 'settings.ini'
|
||||
settings = QtCore.QSettings(str(outside), QtCore.QSettings.Format.IniFormat)
|
||||
|
||||
# Constructing this object does not write; rejection must precede writes.
|
||||
with self.assertRaisesRegex(AssertionError, 'escaped sandbox'):
|
||||
assertIsolatedSettings(settings)
|
||||
|
||||
|
||||
class NavigationBehaviorTest(unittest.TestCase):
|
||||
|
||||
@@ -168,7 +168,7 @@ class QRCodeExportScalabilityTest(unittest.TestCase):
|
||||
self.assertEqual(appendExportItem.call_count, expected)
|
||||
|
||||
def testGenerationYieldsToAnUnrelatedQtEvent(self):
|
||||
"""Deliver unrelated work after one attempt and before batch completion."""
|
||||
"""Deliver unrelated work during generation, before batch completion."""
|
||||
profiles = self.profiles(6)
|
||||
attempts = []
|
||||
marker = []
|
||||
@@ -178,6 +178,12 @@ class QRCodeExportScalabilityTest(unittest.TestCase):
|
||||
"""Record one exported snapshot."""
|
||||
attempts.append(profile.itemRemark)
|
||||
|
||||
if len(attempts) == 1:
|
||||
# Zero-timer ordering is platform-dependent. Queue the marker
|
||||
# only once generation has started, then require it to run
|
||||
# before all profiles finish rather than after exactly one.
|
||||
QtCore.QTimer.singleShot(0, lambda: marker.append(len(attempts)))
|
||||
|
||||
return f'socks://{len(attempts)}.example:1080#Fixture'
|
||||
|
||||
with mock.patch(
|
||||
@@ -191,13 +197,14 @@ class QRCodeExportScalabilityTest(unittest.TestCase):
|
||||
side_effect=self.qrImage,
|
||||
):
|
||||
result = window.startExportByIndex(range(len(profiles)))
|
||||
QtCore.QTimer.singleShot(0, lambda: marker.append(len(attempts)))
|
||||
|
||||
self.assertIs(result, window)
|
||||
self.assertEqual(attempts, [])
|
||||
self.assertTrue(window.isVisible())
|
||||
self.assertTrue(waitFor(lambda: bool(marker)))
|
||||
self.assertEqual(marker, [1])
|
||||
self.assertEqual(len(marker), 1)
|
||||
self.assertGreaterEqual(marker[0], 1)
|
||||
self.assertLess(marker[0], len(profiles))
|
||||
self.assertTrue(waitFor(lambda: not window.isExporting()))
|
||||
|
||||
self.assertEqual(len(attempts), len(profiles))
|
||||
|
||||
Reference in New Issue
Block a user