""" KIN-122 regression: rebuild-frontend.sh должен запускать npm install перед npm run build, если package.json изменился (новее node_modules). """ import os import stat from pathlib import Path SCRIPT_PATH = Path(__file__).parent.parent / "scripts" / "rebuild-frontend.sh" class TestKIN122RebuildFrontendNpmInstall: """Структурные тесты: скрипт содержит условный npm install перед npm run build.""" def test_script_exists(self): assert SCRIPT_PATH.is_file(), f"rebuild-frontend.sh not found at {SCRIPT_PATH}" def test_script_is_executable(self): mode = SCRIPT_PATH.stat().st_mode assert mode & stat.S_IXUSR, "rebuild-frontend.sh должен быть исполняемым" def test_script_contains_npm_install_conditional(self): """Скрипт должен содержать условный блок npm install (KIN-122).""" content = SCRIPT_PATH.read_text() assert "npm install" in content, ( "rebuild-frontend.sh должен содержать 'npm install'" ) def test_script_npm_install_guarded_by_condition(self): """npm install должен быть внутри if-блока, а не вызываться безусловно.""" content = SCRIPT_PATH.read_text() lines = content.splitlines() # Найти строку с npm install npm_install_line_idx = next( (i for i, line in enumerate(lines) if "npm install" in line and "if" not in line), None, ) assert npm_install_line_idx is not None, "Строка с 'npm install' не найдена" # Должен быть if-блок выше preceding = "\n".join(lines[:npm_install_line_idx]) assert "if" in preceding, ( "npm install должен быть внутри условного блока" ) def test_script_checks_node_modules_existence(self): """Условие должно проверять наличие node_modules.""" content = SCRIPT_PATH.read_text() assert "node_modules" in content, ( "Скрипт должен проверять наличие node_modules" ) def test_script_checks_package_json_mtime(self): """Условие должно сравнивать mtime package.json с node_modules (флаг -nt).""" content = SCRIPT_PATH.read_text() assert "-nt" in content, ( "Скрипт должен использовать '-nt' для сравнения mtime package.json и node_modules" ) def test_npm_install_before_npm_run_build(self): """npm install должен стоять раньше npm run build в скрипте.""" content = SCRIPT_PATH.read_text() install_pos = content.find("npm install") build_pos = content.find("npm run build") assert install_pos != -1, "npm install не найден в скрипте" assert build_pos != -1, "npm run build не найден в скрипте" assert install_pos < build_pos, ( "npm install должен стоять раньше npm run build" ) def test_npm_run_build_always_runs(self): """npm run build должен вызываться вне условного блока — всегда выполняется.""" content = SCRIPT_PATH.read_text() lines = content.splitlines() # Найти строку с npm run build (не внутри if-блока) # Ищем строку, которая содержит "npm run build" и не является частью if-условия build_lines = [ line for line in lines if "npm run build" in line and line.strip().startswith("npm run build") ] assert len(build_lines) >= 1, ( "npm run build должен быть безусловным вызовом" )