mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
Add #remoteterm as default channel
This commit is contained in:
@@ -261,6 +261,13 @@ async def run_migrations(conn: aiosqlite.Connection) -> int:
|
||||
await set_version(conn, 32)
|
||||
applied += 1
|
||||
|
||||
# Migration 33: Seed #remoteterm channel on initial install
|
||||
if version < 33:
|
||||
logger.info("Applying migration 33: seed #remoteterm channel")
|
||||
await _migrate_033_seed_remoteterm_channel(conn)
|
||||
await set_version(conn, 33)
|
||||
applied += 1
|
||||
|
||||
if applied > 0:
|
||||
logger.info(
|
||||
"Applied %d migration(s), schema now at version %d", applied, await get_version(conn)
|
||||
@@ -1926,3 +1933,21 @@ async def _migrate_032_add_community_mqtt_columns(conn: aiosqlite.Connection) ->
|
||||
await conn.execute(f"ALTER TABLE app_settings ADD COLUMN {col_name} {col_def}")
|
||||
|
||||
await conn.commit()
|
||||
|
||||
|
||||
async def _migrate_033_seed_remoteterm_channel(conn: aiosqlite.Connection) -> None:
|
||||
"""Seed the #remoteterm hashtag channel so new installs have it by default.
|
||||
|
||||
Uses INSERT OR IGNORE so it's a no-op if the channel already exists
|
||||
(e.g. existing users who already added it manually). The channels table
|
||||
is created by the base schema before migrations run, so it always exists
|
||||
in production.
|
||||
"""
|
||||
try:
|
||||
await conn.execute(
|
||||
"INSERT OR IGNORE INTO channels (key, name, is_hashtag, on_radio) VALUES (?, ?, ?, ?)",
|
||||
("8959AE053F2201801342A1DBDDA184F6", "#remoteterm", 1, 0),
|
||||
)
|
||||
await conn.commit()
|
||||
except Exception:
|
||||
logger.debug("Skipping #remoteterm seed (channels table not ready)")
|
||||
|
||||
@@ -96,9 +96,9 @@ class TestSyncChannelsFromRadio:
|
||||
data = response.json()
|
||||
assert data["synced"] == 2
|
||||
|
||||
# Verify channels in DB
|
||||
# Verify channels in DB (2 synced + #remoteterm seed)
|
||||
channels = await ChannelRepository.get_all()
|
||||
assert len(channels) == 2
|
||||
assert len(channels) == 3
|
||||
|
||||
keys = {ch.key for ch in channels}
|
||||
assert secret_a.hex().upper() in keys
|
||||
|
||||
@@ -100,8 +100,8 @@ class TestMigration001:
|
||||
# Run migrations
|
||||
applied = await run_migrations(conn)
|
||||
|
||||
assert applied == 32 # All migrations run
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 33 # All migrations run
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify columns exist by inserting and selecting
|
||||
await conn.execute(
|
||||
@@ -183,9 +183,9 @@ class TestMigration001:
|
||||
applied1 = await run_migrations(conn)
|
||||
applied2 = await run_migrations(conn)
|
||||
|
||||
assert applied1 == 32 # All migrations run
|
||||
assert applied1 == 33 # All migrations run
|
||||
assert applied2 == 0 # No migrations on second run
|
||||
assert await get_version(conn) == 32
|
||||
assert await get_version(conn) == 33
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
@@ -246,8 +246,8 @@ class TestMigration001:
|
||||
applied = await run_migrations(conn)
|
||||
|
||||
# All migrations applied (version incremented) but no error
|
||||
assert applied == 32
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 33
|
||||
assert await get_version(conn) == 33
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
@@ -376,8 +376,8 @@ class TestMigration013:
|
||||
|
||||
# Run migration 13 (plus 14-33 which also run)
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 20
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 21
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify bots array was created with migrated data
|
||||
cursor = await conn.execute("SELECT bots FROM app_settings WHERE id = 1")
|
||||
@@ -497,7 +497,7 @@ class TestMigration018:
|
||||
assert await cursor.fetchone() is not None
|
||||
|
||||
await run_migrations(conn)
|
||||
assert await get_version(conn) == 32
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify autoindex is gone
|
||||
cursor = await conn.execute(
|
||||
@@ -575,8 +575,8 @@ class TestMigration018:
|
||||
await conn.commit()
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 15 # Migrations 18-32 run (18+19 skip internally)
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 16 # Migrations 18-33 run (18+19 skip internally)
|
||||
assert await get_version(conn) == 33
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
@@ -648,7 +648,7 @@ class TestMigration019:
|
||||
assert await cursor.fetchone() is not None
|
||||
|
||||
await run_migrations(conn)
|
||||
assert await get_version(conn) == 32
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify autoindex is gone
|
||||
cursor = await conn.execute(
|
||||
@@ -714,8 +714,8 @@ class TestMigration020:
|
||||
assert (await cursor.fetchone())[0] == "delete"
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 13 # Migrations 20-32
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 14 # Migrations 20-33
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify WAL mode
|
||||
cursor = await conn.execute("PRAGMA journal_mode")
|
||||
@@ -745,7 +745,7 @@ class TestMigration020:
|
||||
await set_version(conn, 20)
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 12 # Migrations 21-32 still run
|
||||
assert applied == 13 # Migrations 21-33 still run
|
||||
|
||||
# Still WAL + INCREMENTAL
|
||||
cursor = await conn.execute("PRAGMA journal_mode")
|
||||
@@ -803,8 +803,8 @@ class TestMigration028:
|
||||
await conn.commit()
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 5
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 6
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify payload_hash column is now BLOB
|
||||
cursor = await conn.execute("PRAGMA table_info(raw_packets)")
|
||||
@@ -873,8 +873,8 @@ class TestMigration028:
|
||||
await conn.commit()
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 5 # Version still bumped
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 6 # Version still bumped
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify data unchanged
|
||||
cursor = await conn.execute("SELECT payload_hash FROM raw_packets")
|
||||
@@ -923,8 +923,8 @@ class TestMigration032:
|
||||
await conn.commit()
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 1
|
||||
assert await get_version(conn) == 32
|
||||
assert applied == 2
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
# Verify all columns exist with correct defaults
|
||||
cursor = await conn.execute(
|
||||
@@ -941,3 +941,94 @@ class TestMigration032:
|
||||
assert row["community_mqtt_email"] == ""
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
|
||||
class TestMigration033:
|
||||
"""Test migration 033: seed #remoteterm channel."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_migration_seeds_remoteterm_channel(self):
|
||||
"""Migration inserts the #remoteterm channel for new installs."""
|
||||
conn = await aiosqlite.connect(":memory:")
|
||||
conn.row_factory = aiosqlite.Row
|
||||
try:
|
||||
await set_version(conn, 32)
|
||||
await conn.execute("""
|
||||
CREATE TABLE channels (
|
||||
key TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
is_hashtag INTEGER DEFAULT 0,
|
||||
on_radio INTEGER DEFAULT 0
|
||||
)
|
||||
""")
|
||||
# Minimal app_settings so earlier migrations don't fail
|
||||
await conn.execute("""
|
||||
CREATE TABLE app_settings (
|
||||
id INTEGER PRIMARY KEY,
|
||||
community_mqtt_enabled INTEGER DEFAULT 0,
|
||||
community_mqtt_iata TEXT DEFAULT '',
|
||||
community_mqtt_broker_host TEXT DEFAULT '',
|
||||
community_mqtt_broker_port INTEGER DEFAULT 443,
|
||||
community_mqtt_email TEXT DEFAULT ''
|
||||
)
|
||||
""")
|
||||
await conn.commit()
|
||||
|
||||
applied = await run_migrations(conn)
|
||||
assert applied == 1
|
||||
assert await get_version(conn) == 33
|
||||
|
||||
cursor = await conn.execute(
|
||||
"SELECT key, name, is_hashtag, on_radio FROM channels WHERE key = ?",
|
||||
("8959AE053F2201801342A1DBDDA184F6",),
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
assert row is not None
|
||||
assert row["name"] == "#remoteterm"
|
||||
assert row["is_hashtag"] == 1
|
||||
assert row["on_radio"] == 0
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_migration_does_not_overwrite_existing_channel(self):
|
||||
"""Migration is a no-op if #remoteterm already exists."""
|
||||
conn = await aiosqlite.connect(":memory:")
|
||||
conn.row_factory = aiosqlite.Row
|
||||
try:
|
||||
await set_version(conn, 32)
|
||||
await conn.execute("""
|
||||
CREATE TABLE channels (
|
||||
key TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
is_hashtag INTEGER DEFAULT 0,
|
||||
on_radio INTEGER DEFAULT 0
|
||||
)
|
||||
""")
|
||||
await conn.execute("""
|
||||
CREATE TABLE app_settings (
|
||||
id INTEGER PRIMARY KEY,
|
||||
community_mqtt_enabled INTEGER DEFAULT 0,
|
||||
community_mqtt_iata TEXT DEFAULT '',
|
||||
community_mqtt_broker_host TEXT DEFAULT '',
|
||||
community_mqtt_broker_port INTEGER DEFAULT 443,
|
||||
community_mqtt_email TEXT DEFAULT ''
|
||||
)
|
||||
""")
|
||||
# Pre-existing channel with on_radio=1 (user added it to radio)
|
||||
await conn.execute(
|
||||
"INSERT INTO channels (key, name, is_hashtag, on_radio) VALUES (?, ?, ?, ?)",
|
||||
("8959AE053F2201801342A1DBDDA184F6", "#remoteterm", 1, 1),
|
||||
)
|
||||
await conn.commit()
|
||||
|
||||
await run_migrations(conn)
|
||||
|
||||
cursor = await conn.execute(
|
||||
"SELECT on_radio FROM channels WHERE key = ?",
|
||||
("8959AE053F2201801342A1DBDDA184F6",),
|
||||
)
|
||||
row = await cursor.fetchone()
|
||||
assert row["on_radio"] == 1 # Not overwritten
|
||||
finally:
|
||||
await conn.close()
|
||||
|
||||
@@ -15,7 +15,7 @@ class TestStatisticsEmpty:
|
||||
|
||||
assert result["contact_count"] == 0
|
||||
assert result["repeater_count"] == 0
|
||||
assert result["channel_count"] == 0
|
||||
assert result["channel_count"] == 1 # #remoteterm seed from migration 33
|
||||
assert result["total_packets"] == 0
|
||||
assert result["decrypted_packets"] == 0
|
||||
assert result["undecrypted_packets"] == 0
|
||||
@@ -67,7 +67,7 @@ class TestStatisticsCounts:
|
||||
await conn.commit()
|
||||
|
||||
result = await StatisticsRepository.get_all()
|
||||
assert result["channel_count"] == 1
|
||||
assert result["channel_count"] == 2 # test-chan + #remoteterm seed
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_message_type_counts(self, test_db):
|
||||
|
||||
Reference in New Issue
Block a user