Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions promociones_procesadas/promotion_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"title": "Summer Sale 2024",
"description": "Get 50% off on all items this summer!",
"discount_code": "SUMMER50",
"valid_until": "2024-08-31T23:59:59Z"
}
64 changes: 64 additions & 0 deletions scripts/auto_deploy_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/usr/bin/env python3
# scripts/auto_deploy_v2.py
import os
import sys
import json
import urllib.error
import urllib.request
from typing import Any, Dict


def validar_promocion(data: Dict[str, Any]) -> None:
campos_requeridos = ["title", "description", "discount_code", "valid_until"]
for campo in campos_requeridos:
if campo not in data:
raise ValueError(f"Falta el campo requerido: {campo}")

def main():
if len(sys.argv) < 2:
print("Uso: python3 auto_deploy_v2.py <ruta_al_archivo_json>")
sys.exit(1)

archivo = sys.argv[1]

try:
with open(archivo, 'r', encoding='utf-8') as f:
data = json.load(f)
except FileNotFoundError:
print(f"Error: No se encontró el archivo '{archivo}'.")
sys.exit(1)
except json.JSONDecodeError as e:
print(f"Error: El archivo no es un JSON válido. Detalles: {e}")
sys.exit(1)

try:
validar_promocion(data)
except ValueError as e:
print(f"Error de validación: {e}")
sys.exit(1)

api_key = os.environ.get("TRYONYOU_API_KEY")
if not api_key:
print("Error: La variable de entorno TRYONYOU_API_KEY no está definida.")
sys.exit(1)

api_url = "https://api.tryonyou.pro/v1/promotions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}

try:
req = urllib.request.Request(api_url, data=json.dumps(data).encode("utf-8"), headers=headers, method="POST")
response = urllib.request.urlopen(req)
response_body = response.read().decode('utf-8')
print(f"Despliegue exitoso. Respuesta de la API: {response_body}")
except urllib.error.URLError as e:
print(f"Error en el despliegue de red o HTTP: {e}")
sys.exit(1)
except Exception as e:
print(f"Error inesperado durante el despliegue: {e}")
sys.exit(1)

if __name__ == "__main__":
main()
31 changes: 31 additions & 0 deletions scripts/auto_deploy_v2.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# scripts/auto_deploy_v2.sh

if [ -z "$1" ]; then
echo "Error: Debes proporcionar la ruta a un archivo JSON de promoción."
echo "Uso: $0 <ruta_al_archivo_json>"
exit 1
fi

FILE_PATH="$1"

# Obtenemos la ruta absoluta del directorio del script bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PYTHON_SCRIPT="$SCRIPT_DIR/auto_deploy_v2.py"

echo "Iniciando despliegue de promoción: $FILE_PATH"

python3 "$PYTHON_SCRIPT" "$FILE_PATH"
EXIT_CODE=$?

if [ $EXIT_CODE -eq 0 ]; then
echo "========================================="
echo "✅ Despliegue exitoso."
echo "========================================="
exit 0
else
echo "========================================="
echo "❌ Error en el despliegue. Revisa los logs arriba."
echo "========================================="
exit $EXIT_CODE
fi
107 changes: 107 additions & 0 deletions tests/test_auto_deploy_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import os
import json
import pathlib
import subprocess
from unittest import mock

import pytest

# Assuming we want to run the python script via subprocess for end-to-end tests
# or import and test specific functions if needed. We'll use subprocess for simplicity
# to cover arguments, env vars and outputs properly.

SCRIPT_PATH = os.path.join(os.path.dirname(__file__), "..", "scripts", "auto_deploy_v2.py")

@pytest.fixture
def valid_json_path(tmp_path: pathlib.Path) -> str:
data = {
"title": "Test Promo",
"description": "50% off",
"discount_code": "TEST50",
"valid_until": "2024-12-31T23:59:59Z"
}
p = tmp_path / "valid_promo.json"
p.write_text(json.dumps(data), encoding='utf-8')
return str(p)

@pytest.fixture
def invalid_json_path(tmp_path: pathlib.Path) -> str:
data = {
"title": "Test Promo",
"discount_code": "TEST50"
# missing description and valid_until
}
p = tmp_path / "invalid_promo.json"
p.write_text(json.dumps(data), encoding='utf-8')
return str(p)

def test_missing_argument() -> None:
result = subprocess.run(
["python3", SCRIPT_PATH],
capture_output=True,
text=True
)
assert result.returncode == 1
assert "Uso:" in result.stdout

def test_file_not_found() -> None:
result = subprocess.run(
["python3", SCRIPT_PATH, "nonexistent_file.json"],
capture_output=True,
text=True
)
assert result.returncode == 1
assert "No se encontró el archivo" in result.stdout

def test_invalid_json(invalid_json_path: str) -> None:
result = subprocess.run(
["python3", SCRIPT_PATH, invalid_json_path],
capture_output=True,
text=True
)
assert result.returncode == 1
assert "Error de validación" in result.stdout
assert "Falta el campo requerido" in result.stdout

def test_missing_api_key(valid_json_path: str, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.delenv("TRYONYOU_API_KEY", raising=False)
result = subprocess.run(
["python3", SCRIPT_PATH, valid_json_path],
capture_output=True,
text=True,
env=os.environ
)
assert result.returncode == 1
assert "TRYONYOU_API_KEY no está definida" in result.stdout

@mock.patch("urllib.request.urlopen")
def test_successful_deploy(mock_urlopen: mock.MagicMock, valid_json_path: str, monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("TRYONYOU_API_KEY", "test_key")

mock_response = mock.MagicMock()
mock_response.read.return_value = b'{"status": "success"}'
mock_urlopen.return_value = mock_response

# Import script as module to mock urlopen easily instead of subprocess
import sys
import importlib.util
spec = importlib.util.spec_from_file_location("auto_deploy", SCRIPT_PATH)
assert spec is not None
auto_deploy = importlib.util.module_from_spec(spec)

# Mock sys.argv
test_args = ["auto_deploy_v2.py", valid_json_path]
with mock.patch.object(sys, 'argv', test_args):
# We need to capture stdout for asserting
from io import StringIO
with mock.patch('sys.stdout', new_callable=StringIO) as mock_stdout:
assert spec.loader is not None
spec.loader.exec_module(auto_deploy)

# Since auto_deploy is constructed dynamically, mypy/pyright doesn't know it has main()
auto_deploy.main()
output = mock_stdout.getvalue()

assert "Despliegue exitoso" in output
assert '{"status": "success"}' in output
mock_urlopen.assert_called_once()
Loading