import hashlib import sqlite3 import tempfile import unittest from pathlib import Path import publish_argus as publisher class PublicationTests(unittest.TestCase): def test_catalog_retains_latest_with_backup_and_other_apps_unchanged(self): with tempfile.TemporaryDirectory() as temp: root = Path(temp) publisher.ROOT = root (root / 'backups').mkdir() (root / 'Packages' / 'qsafe').mkdir(parents=True) old = root / 'Packages/qsafe/old.apk' old.write_bytes(b'old synthetic APK') with sqlite3.connect(root / 'argus.db') as db: db.executescript(''' CREATE TABLE Apps (Id TEXT PRIMARY KEY, Slug TEXT, Name TEXT, Summary TEXT, Description TEXT, Icon TEXT, Extra TEXT, AndroidPackageName TEXT, IsListed INTEGER, CreatedAt TEXT, UpdatedAt TEXT); CREATE TABLE Releases (Id TEXT PRIMARY KEY, CatalogAppId TEXT REFERENCES Apps(Id), Version TEXT, Channel TEXT, Platform TEXT, PackageKind TEXT, AndroidVersionCode INTEGER, OriginalFileName TEXT, StoredRelativePath TEXT, ContentType TEXT, PackageSizeBytes INTEGER, Sha256 TEXT, Notes TEXT, PublishedAt TEXT); CREATE TRIGGER Argus_RetainLatestAfterInsert AFTER INSERT ON Releases BEGIN DELETE FROM Releases WHERE CatalogAppId=NEW.CatalogAppId AND rowid NOT IN (SELECT rowid FROM Releases WHERE CatalogAppId=NEW.CatalogAppId ORDER BY AndroidVersionCode DESC LIMIT 1); END; INSERT INTO Apps VALUES ('qsafe-id','qsafe','QSafe','old','old',NULL,NULL,'ru.kusoft.qsafe',1,'old','old'); INSERT INTO Apps VALUES ('other-id','other','Other','keep','keep',NULL,NULL,'other.package',1,'old','old'); ''') db.execute('INSERT INTO Releases VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)', ('old-release', 'qsafe-id', '1.0.0', 'stable', 'android', 'apk', 3, 'old.apk', 'qsafe/old.apk', 'application/vnd.android.package-archive', old.stat().st_size, hashlib.sha256(old.read_bytes()).hexdigest(), 'old', 'old')) new = root / 'QSafe-1.0.1.apk' new.write_bytes(b'new synthetic APK') metadata = dict(version='1.0.1', versionCode=4, size=new.stat().st_size, sha256=hashlib.sha256(new.read_bytes()).hexdigest(), expectedPreviousVersionCode=3, summary='new', description='new', notes='LAN only vault; Argus updates') result = publisher.publish(new, metadata) self.assertTrue(result['unrelatedCatalogRowsUnchanged']) self.assertEqual(b'old synthetic APK', old.read_bytes()) with sqlite3.connect(root / 'argus.db') as db: self.assertEqual(1, db.execute("SELECT COUNT(*) FROM Releases WHERE CatalogAppId='qsafe-id'").fetchone()[0]) self.assertEqual(('keep', 'keep'), db.execute("SELECT Summary,Description FROM Apps WHERE Id='other-id'").fetchone()) self.assertTrue(publisher.publish(new, metadata)['alreadyPublished']) self.assertEqual(b'old synthetic APK', (Path(result['backup']) / 'Packages/qsafe/old.apk').read_bytes()) wrong = dict(metadata, version='1.0.2', versionCode=5) with self.assertRaises(RuntimeError): publisher.publish(new, wrong) if __name__ == '__main__': unittest.main()