Prva verzija mini web serverja (flask). Hvala, Github Copilot.

This commit is contained in:
2026-03-05 18:15:27 +01:00
parent 9e32e58c4c
commit 6ed45d2ebc
13 changed files with 1164 additions and 5 deletions

143
tests/test_api.py Normal file
View File

@@ -0,0 +1,143 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import time
import json
BASE_URL = 'http://127.0.0.1:5000'
def test_api():
"""Testiraj web API"""
print("=" * 60)
print("Testiranje Web API-ja")
print("=" * 60)
# Testiranje GET /api/state
print("\n1. Test GET /api/state (početno stanje)")
try:
response = requests.get(f'{BASE_URL}/api/state')
data = response.json()
print(f" Status: {response.status_code}")
print(f" Current text: {data.get('current_text', '')[:50]}...")
print(f" Caps mode: {data.get('caps_mode')}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/load_song
print("\n2. Test POST /api/load_song (broj 1)")
try:
response = requests.post(
f'{BASE_URL}/api/load_song',
json={'song_number': '1'}
)
print(f" Status: {response.status_code}")
data = response.json()
print(f" Response: {data}")
# Pričekaj da se pesma naloži
time.sleep(0.5)
# Provjeri stanje
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Current text: {state.get('current_text', '')[:50]}...")
print(f" Can next: {state.get('can_next')}")
print(f" Can prev: {state.get('can_prev')}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/next_page
print("\n3. Test POST /api/next_page")
try:
response = requests.post(f'{BASE_URL}/api/next_page')
print(f" Status: {response.status_code}")
# Provjeri stanje
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Page info: {state.get('page_info')}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/prev_page
print("\n4. Test POST /api/prev_page")
try:
response = requests.post(f'{BASE_URL}/api/prev_page')
print(f" Status: {response.status_code}")
# Provjeri stanje
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Page info: {state.get('page_info')}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/toggle_caps
print("\n5. Test POST /api/toggle_caps")
try:
response = requests.post(f'{BASE_URL}/api/toggle_caps')
print(f" Status: {response.status_code}")
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Caps mode: {state.get('caps_mode')}")
print(f" Text (caps): {state.get('current_text', '')[:50]}...")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/clear_screen
print("\n6. Test POST /api/clear_screen")
try:
response = requests.post(f'{BASE_URL}/api/clear_screen')
print(f" Status: {response.status_code}")
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Current text: {state.get('current_text', '')[:50]}...")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje POST /api/search_songs
print("\n7. Test POST /api/search_songs")
try:
response = requests.post(
f'{BASE_URL}/api/search_songs',
json={'query': 'pesem'}
)
print(f" Status: {response.status_code}")
data = response.json()
results = data.get('results', [])
print(f" Rezultati: {results}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
# Testiranje GET /
print("\n8. Test GET / (HTML stranicu)")
try:
response = requests.get(f'{BASE_URL}/')
print(f" Status: {response.status_code}")
print(f" HTML length: {len(response.text)} bytes")
print(f" Contains 'Flask': {'Flask' in response.text}")
print(" ✓ PASS")
except Exception as e:
print(f" ✗ FAIL: {e}")
print("\n" + "=" * 60)
print("Testiranje završeno!")
print("=" * 60)
if __name__ == "__main__":
test_api()

185
tests/test_integration.py Normal file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Integracijski test Flask servera s mock aplikacijom
"""
import sqlite3
import json
import sys
import os
import time
import threading
import requests
from web.server import set_projector_app, run_server
# Simuliraj SongProjector stanu
class MockSongProjector:
def __init__(self):
self.current_song = None
self.pages = []
self.current_page_index = 0
self.song_number = ""
self.song_number_last = ""
self.all_caps_mode = False
self.waiting_for_song = True
# Otvori bazu
try:
self.conn = sqlite3.connect(f"file:songs.db?mode=ro", uri=True, check_same_thread=False)
self.cursor = self.conn.cursor()
except:
self.conn = None
self.cursor = None
# Čitaj settings
with open('settings.json', 'r', encoding='utf-8') as f:
self.settings = json.load(f)
def load_song(self):
"""Simulacija load_song metode"""
if not self.song_number or not self.cursor:
return
song_number_to_load = self.song_number # Spremi broj prije nego što ga obriši
try:
song_id = int(song_number_to_load)
self.cursor.execute("SELECT lyrics FROM songs WHERE id= ?", (song_id,))
result = self.cursor.fetchone()
if result:
lyrics = result[0]
# Jednostavna podijela pesme na samo jednu stranicu za test
self.pages = [lyrics]
self.current_page_index = 0
self.waiting_for_song = False
self.song_number_last = song_number_to_load
else:
self.pages = []
self.waiting_for_song = True
except:
self.pages = []
finally:
self.song_number = ""
def next_page(self):
if self.pages and self.current_page_index + 1 < len(self.pages):
self.current_page_index += 1
def prev_page(self):
if self.pages and self.current_page_index > 0:
self.current_page_index -= 1
def clear_screen(self):
self.pages = []
self.current_page_index = 0
self.waiting_for_song = True
def show_page(self):
pass # Dummy
def toggle_caps(self):
self.all_caps_mode = not self.all_caps_mode
self.show_page()
# Kreiraj mock aplikaciju
print("Iniciijalisiranje mock aplikacije...")
mock_app = MockSongProjector()
set_projector_app(mock_app)
# Pokreni Flask server u zvjenoj niti
print("Pokretanje Flask servera...")
web_port = mock_app.settings.get('web_port', 5000)
server_thread = threading.Thread(
target=run_server,
args=('127.0.0.1', web_port),
daemon=True
)
server_thread.start()
# Čekaj da se server pokreće
time.sleep(2)
print("=" * 60)
print("Test Flask API-ja")
print("=" * 60)
BASE_URL = f'http://127.0.0.1:{web_port}'
try:
print("\n1. GET / (HTML stranica)")
response = requests.get(f'{BASE_URL}/')
print(f" Status: {response.status_code}")
print(f" HTML size: {len(response.text)} bytes")
assert response.status_code == 200, f"Expected 200, got {response.status_code}"
print(" PASS")
print("\n2. GET /api/state (initial state)")
response = requests.get(f'{BASE_URL}/api/state')
data = response.json()
print(f" Status: {response.status_code}")
print(f" Current text: {data.get('current_text', '')[:50]}...")
assert response.status_code == 200
print(" PASS")
print("\n3. POST /api/load_song (song 1)")
response = requests.post(
f'{BASE_URL}/api/load_song',
json={'song_number': '1'}
)
print(f" Status: {response.status_code}")
time.sleep(0.5)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Text loaded: {state.get('current_text', '')[:50]}...")
assert 'Prva linija' in state.get('current_text', ''), "Song not loaded"
print(" PASS")
print("\n4. POST /api/toggle_caps")
response = requests.post(f'{BASE_URL}/api/toggle_caps')
print(f" Status: {response.status_code}")
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Caps mode: {state.get('caps_mode')}")
print(f" Text (caps): {state.get('current_text', '')[:50]}...")
print(" PASS")
print("\n5. POST /api/clear_screen")
response = requests.post(f'{BASE_URL}/api/clear_screen')
print(f" Status: {response.status_code}")
time.sleep(0.3)
response = requests.get(f'{BASE_URL}/api/state')
state = response.json()
print(f" Pages cleared: {len(mock_app.pages) == 0}")
print(f" Current text after clear: '{state.get('current_text')}'")
assert state.get('current_text', '').startswith('Pripravljeno'), "Clear screen didn't update state"
print(" PASS")
print("\n6. POST /api/search_songs")
response = requests.post(
f'{BASE_URL}/api/search_songs',
json={'query': 'pesem'}
)
data = response.json()
print(f" Status: {response.status_code}")
print(f" Results: {data.get('results', [])}")
print(" PASS")
print("\n" + "=" * 60)
print("ALL TESTS PASSED!")
print("=" * 60)
print(f"\nFlask server available at: http://127.0.0.1:{web_port}")
except AssertionError as e:
print(f" FAIL: {e}")
sys.exit(1)
except Exception as e:
print(f" FAIL: {e}")
import traceback
traceback.print_exc()
sys.exit(1)

106
tests/test_mock.py Normal file
View File

@@ -0,0 +1,106 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Test Flask servera brez Tkinter aplikacije
"""
import sqlite3
import json
import sys
import os
# Simuliraj SongProjector stanu
class MockSongProjector:
def __init__(self):
self.current_song = None
self.pages = []
self.current_page_index = 0
self.song_number = ""
self.song_number_last = ""
self.all_caps_mode = False
self.waiting_for_song = True
# Otvori bazu
try:
self.conn = sqlite3.connect(f"file:songs.db?mode=ro", uri=True)
self.cursor = self.conn.cursor()
except:
self.conn = None
self.cursor = None
# Čitaj settings
with open('settings.json', 'r', encoding='utf-8') as f:
self.settings = json.load(f)
def load_song(self):
"""Simulacija load_song metode"""
if not self.song_number or not self.cursor:
return
try:
song_id = int(self.song_number)
self.cursor.execute("SELECT lyrics FROM songs WHERE id=?", (song_id,))
result = self.cursor.fetchone()
if result:
lyrics = result[0]
self.pages = [lyrics] # Jednostavno - brez stranica
self.current_page_index = 0
self.waiting_for_song = False
self.song_number_last = self.song_number
else:
self.pages = []
self.waiting_for_song = True
except:
self.pages = []
finally:
self.song_number = ""
def next_page(self):
if self.pages and self.current_page_index + 1 < len(self.pages):
self.current_page_index += 1
def prev_page(self):
if self.pages and self.current_page_index > 0:
self.current_page_index -= 1
def clear_screen(self):
self.pages = []
self.current_page_index = 0
self.waiting_for_song = True
def show_page(self):
pass # Dummy
# Kreiraj mock aplikacijo
app_mock = MockSongProjector()
# Testiraj
print("=" * 60)
print("Test MockSongProjector")
print("=" * 60)
print("\n1. Početno stanje:")
print(f" Pages: {len(app_mock.pages)}")
print(f" Current page: {app_mock.current_page_index}")
print(f" Waiting for song: {app_mock.waiting_for_song}")
print("\n2. Naloži pesmu broj 1:")
app_mock.song_number = "1"
app_mock.load_song()
print(f" Pages: {len(app_mock.pages)}")
print(f" Current page: {app_mock.current_page_index}")
print(f" Waiting for song: {app_mock.waiting_for_song}")
print(f" Text: {(app_mock.pages[0] if app_mock.pages else 'N/A')[:50]}...")
print("\n3. Očisti ekran:")
app_mock.clear_screen()
print(f" Pages: {len(app_mock.pages)}")
print(f" Waiting for song: {app_mock.waiting_for_song}")
print("\n4. Web konfiguracija:")
print(f" Web port: {app_mock.settings.get('web_port', 'nije postavljeno')}")
print("\n" + "=" * 60)
print("Svi testovi su prošli!")
print("=" * 60)