2 changed files with 200 additions and 0 deletions
@ -0,0 +1,197 @@ |
|||
#!/usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
|
|||
import os |
|||
import pytest |
|||
import tempfile |
|||
from src import boot |
|||
from typing import Callable |
|||
from unittest.mock import patch, mock_open |
|||
|
|||
|
|||
@pytest.fixture(autouse=True) |
|||
def init_opts(): |
|||
boot.init_opts() |
|||
yield |
|||
|
|||
|
|||
@pytest.fixture |
|||
def temp_dir_setup(): |
|||
env_backup = os.environ.copy() |
|||
os.environ['CERT_DIR'] = (cert_dir := tempfile.mkdtemp()) |
|||
os.environ['TEMP_DIR'] = (temp_dir := tempfile.mkdtemp()) |
|||
os.environ['WORK_DIR'] = (work_dir := tempfile.mkdtemp()) |
|||
|
|||
yield cert_dir, temp_dir, work_dir |
|||
|
|||
os.environ.clear() |
|||
os.environ.update(env_backup) |
|||
|
|||
|
|||
def convert_builder(keep_port: bool = False, keep_salt: bool = False) -> Callable[[boot.SyncplayOptions], list[str]]: |
|||
def convert(opts: boot.SyncplayOptions) -> list[str]: |
|||
output = boot.sp_convert(opts) |
|||
|
|||
if not keep_port: |
|||
if '--port' in output and '8999' in output: |
|||
if (index := output.index('--port')) + 1 == output.index('8999'): |
|||
output = output[:index] + output[index + 2:] |
|||
|
|||
if not keep_salt: |
|||
if '--salt' in output and '' in output: |
|||
if (index := output.index('--salt')) + 1 == output.index(''): |
|||
output = output[:index] + output[index + 2:] |
|||
|
|||
return output |
|||
|
|||
return convert |
|||
|
|||
|
|||
def test_port() -> None: |
|||
""" |
|||
Test port field of options conversion. |
|||
""" |
|||
convert = convert_builder(keep_port=True) |
|||
assert convert({}) == ['--port', '8999'] # default port |
|||
assert convert({'port': 12345}) == ['--port', '12345'] # custom port |
|||
|
|||
|
|||
def test_password() -> None: |
|||
""" |
|||
Test password field of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({}) == [] |
|||
assert convert({'password': 'PWD'}) == ['--password', 'PWD'] # custom password |
|||
|
|||
|
|||
@patch('src.boot.open', new_callable=mock_open) |
|||
def test_motd(mock_file) -> None: |
|||
""" |
|||
Test motd field of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({}) == [] |
|||
assert convert({'motd': 'MSG'}) == ['--motd-file', '/tmp/motd.data'] |
|||
mock_file.assert_called_with('/tmp/motd.data', 'w', encoding='utf-8') |
|||
mock_file().write.assert_called_with('MSG') |
|||
|
|||
|
|||
def test_salt_handling() -> None: |
|||
""" |
|||
Test salt related handling of options conversion. |
|||
""" |
|||
convert = convert_builder(keep_salt=True) |
|||
assert convert({}) == ['--salt', ''] |
|||
assert convert({'salt': ''}) == ['--salt', ''] |
|||
assert convert({'salt': 'SALT'}) == ['--salt', 'SALT'] |
|||
|
|||
assert convert({'random_salt': True}) == [] |
|||
assert convert({'salt': '', 'random_salt': True}) == ['--salt', ''] |
|||
assert convert({'salt': 'SALT', 'random_salt': True}) == ['--salt', 'SALT'] |
|||
|
|||
|
|||
def test_boolean_flags() -> None: |
|||
""" |
|||
Test boolean flags handling of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({'isolate_rooms': True}) == [f'--isolate-rooms'] |
|||
assert convert({'disable_chat': True}) == [f'--disable-chat'] |
|||
assert convert({'disable_ready': True}) == [f'--disable-ready'] |
|||
|
|||
assert convert({'enable_stats': True}) == ['--stats-db-file', '/data/stats.db'] |
|||
assert convert({'enable_tls': True}) == ['--tls', '/certs/'] |
|||
assert convert({'persistent': True}) == ['--rooms-db-file', '/data/rooms.db'] |
|||
|
|||
|
|||
def test_limited_values() -> None: |
|||
""" |
|||
Test limited values handling of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({'max_username': 20}) == ['--max-username-length', '20'] |
|||
assert convert({'max_chat_message': 500}) == ['--max-chat-message-length', '500'] |
|||
|
|||
|
|||
@patch('src.boot.open', new_callable=mock_open) |
|||
def test_permanent_rooms(mock_file) -> None: |
|||
""" |
|||
Test permanent rooms field of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({'permanent_rooms': ['R1', 'R2', 'R3']}) == ['--permanent-rooms-file', '/tmp/rooms.list'] |
|||
mock_file.assert_called_with('/tmp/rooms.list', 'w', encoding='utf-8') |
|||
mock_file().write.assert_called_with('R1\nR2\nR3') |
|||
|
|||
|
|||
def test_ip_configure() -> None: |
|||
""" |
|||
Test IP configure handling of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
assert convert({}) == [] |
|||
assert convert({'listen_ipv4': '0.0.0.0'}) == ['--ipv4-only', '--interface-ipv4', '0.0.0.0'] |
|||
assert convert({'listen_ipv6': '::'}) == ['--ipv6-only', '--interface-ipv6', '::'] |
|||
assert convert({'listen_ipv4': '0.0.0.0', 'listen_ipv6': '::'}) == ['--interface-ipv4', '0.0.0.0', '--interface-ipv6', '::'] |
|||
|
|||
|
|||
def test_path_env(temp_dir_setup) -> None: |
|||
""" |
|||
Test path env variables of options conversion. |
|||
""" |
|||
convert = convert_builder() |
|||
cert_dir, temp_dir, work_dir = temp_dir_setup |
|||
|
|||
assert convert({'enable_tls': True}) == ['--tls', cert_dir] # tls using CERT_DIR |
|||
|
|||
path = os.path.join(temp_dir, 'motd.data') # motd using TEMP_DIR |
|||
assert convert({'motd': 'MESSAGE'}) == ['--motd-file', path] |
|||
|
|||
path = os.path.join(work_dir, 'stats.db') # stats-db using WORK_DIR |
|||
assert convert({'enable_stats': True}) == ['--stats-db-file', path] |
|||
|
|||
|
|||
def test_full_options() -> None: |
|||
""" |
|||
Test full options conversion. |
|||
""" |
|||
convert = convert_builder(keep_port=True, keep_salt=True) |
|||
options = convert({ |
|||
'port': 12345, |
|||
'password': 'secret', |
|||
'motd': 'Welcome to Syncplay', |
|||
'salt': 'mysalt', |
|||
'random_salt': True, |
|||
'isolate_rooms': True, |
|||
'disable_chat': True, |
|||
'disable_ready': True, |
|||
'enable_stats': True, |
|||
'enable_tls': True, |
|||
'persistent': True, |
|||
'max_username': 20, |
|||
'max_chat_message': 500, |
|||
'permanent_rooms': ['room1', 'room2', 'room3'], |
|||
'listen_ipv4': '0.0.0.0', |
|||
'listen_ipv6': '::' |
|||
}) |
|||
|
|||
expected = [ |
|||
'--port', '12345', |
|||
'--password', 'secret', |
|||
'--motd-file', '/tmp/motd.data', |
|||
'--salt', 'mysalt', |
|||
'--isolate-rooms', |
|||
'--disable-chat', |
|||
'--disable-ready', |
|||
'--stats-db-file', '/data/stats.db', |
|||
'--tls', '/certs/', |
|||
'--rooms-db-file', '/data/rooms.db', |
|||
'--max-username-length', '20', |
|||
'--max-chat-message-length', '500', |
|||
'--permanent-rooms-file', '/tmp/rooms.list', |
|||
'--interface-ipv4', '0.0.0.0', |
|||
'--interface-ipv6', '::' |
|||
] |
|||
|
|||
assert options == expected |
Loading…
Reference in new issue