"""
Integration tests for focus_view_on_point (Feature 08 - Viewport Controls update).
These tests verify the actual implementation of focus_view_on_point
against real Blender viewports.
Testing criteria:
1. Method implementation works
2. Business logic matches BDD scenarios
3. Output is correct
"""
import pytest
from tests.integration.conftest import send_command
class TestFocusViewOnPoint:
"""Tests for focus_view_on_point tool."""
def test_focus_view_basic(self, real_blender_connection):
"""
Feature: Focus view on specific 3D point.
"""
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 1.0,
"y": 2.0,
"z": 3.0
})
assert response["status"] == "success", f"Command failed: {response}"
result = response["result"]
# Verify target is set
assert "target" in result, "Missing target in result"
target = result["target"]
assert target["x"] == 1.0, f"Expected x=1.0, got {target['x']}"
assert target["y"] == 2.0, f"Expected y=2.0, got {target['y']}"
assert target["z"] == 3.0, f"Expected z=3.0, got {target['z']}"
def test_focus_view_with_distance(self, real_blender_connection):
"""
Feature: Focus view with custom distance.
"""
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 0,
"y": 0,
"z": 0,
"distance": 5.0
})
assert response["status"] == "success"
result = response["result"]
assert "view_distance" in result, "Missing view_distance in result"
# Distance should be approximately 5.0
assert abs(result["view_distance"] - 5.0) < 0.1, \
f"Expected distance ~5.0, got {result['view_distance']}"
def test_focus_view_with_axis_alignment(self, real_blender_connection):
"""
Feature: Focus view with axis alignment.
"""
axes = ["FRONT", "BACK", "LEFT", "RIGHT", "TOP", "BOTTOM"]
for axis in axes:
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 0,
"y": 0,
"z": 0,
"view_axis": axis
})
assert response["status"] == "success", \
f"Failed for view_axis={axis}: {response}"
result = response["result"]
assert result.get("view_axis") == axis, \
f"Expected view_axis={axis}, got {result.get('view_axis')}"
def test_focus_view_with_distance_and_axis(self, real_blender_connection):
"""
Feature: Focus view with distance and axis.
"""
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 1,
"y": 1,
"z": 1,
"distance": 3.0,
"view_axis": "FRONT"
})
assert response["status"] == "success"
result = response["result"]
target = result["target"]
assert target["x"] == 1
assert target["y"] == 1
assert target["z"] == 1
assert abs(result["view_distance"] - 3.0) < 0.1
assert result["view_axis"] == "FRONT"
def test_focus_view_origin(self, real_blender_connection):
"""
Feature: Focus view on origin.
"""
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 0,
"y": 0,
"z": 0
})
assert response["status"] == "success"
result = response["result"]
target = result["target"]
assert target["x"] == 0
assert target["y"] == 0
assert target["z"] == 0
def test_focus_view_negative_coordinates(self, real_blender_connection):
"""
Feature: Focus view on negative coordinates.
"""
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": -2.5,
"y": -1.0,
"z": -0.5
})
assert response["status"] == "success"
result = response["result"]
target = result["target"]
assert target["x"] == -2.5
assert target["y"] == -1.0
assert target["z"] == -0.5
def test_focus_view_integration_with_mesh_regions(self, real_blender_connection):
"""
Feature: Navigate to problem area from analyze_mesh_regions.
This tests the workflow of using analyze_mesh_regions to find
problem areas and then navigating to them with focus_view_on_point.
"""
# Create mesh
send_command(real_blender_connection, "execute_code", {
"code": """
import bpy
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_cube_add(size=2)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.subdivide(number_cuts=2)
bpy.ops.object.mode_set(mode='OBJECT')
"""
})
# Get regions
regions_response = send_command(real_blender_connection, "analyze_mesh_regions", {})
assert regions_response["status"] == "success"
regions_result = regions_response["result"]
regions = regions_result.get("regions", [])
if len(regions) > 0:
# Navigate to first region
center = regions[0]["center"]
focus_response = send_command(real_blender_connection, "focus_view_on_point", {
"x": center[0],
"y": center[1],
"z": center[2],
"distance": 2.0
})
assert focus_response["status"] == "success"
print(f"Successfully navigated to region at {center}")
def test_focus_view_integration_with_topology_quality(self, real_blender_connection):
"""
Feature: Navigate to pole location from get_topology_quality.
"""
# Create mesh with poles
send_command(real_blender_connection, "execute_code", {
"code": """
import bpy
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_cube_add(size=2)
"""
})
# Get topology quality to find poles
quality_response = send_command(real_blender_connection, "get_topology_quality", {})
assert quality_response["status"] == "success"
quality_result = quality_response["result"]
pole_locations = quality_result.get("pole_locations", [])
if len(pole_locations) > 0:
# Navigate to first pole
pole = pole_locations[0]
focus_response = send_command(real_blender_connection, "focus_view_on_point", {
"x": pole[0],
"y": pole[1],
"z": pole[2],
"distance": 0.5,
"view_axis": "FRONT"
})
assert focus_response["status"] == "success"
print(f"Successfully navigated to pole at {pole}")
def test_focus_view_maintains_distance_when_not_specified(self, real_blender_connection):
"""
Feature: Focus maintains current distance when not specified.
"""
# Set a known distance first
send_command(real_blender_connection, "focus_view_on_point", {
"x": 0,
"y": 0,
"z": 0,
"distance": 10.0
})
# Focus on different point without specifying distance
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": 1,
"y": 1,
"z": 1
})
assert response["status"] == "success"
result = response["result"]
# Distance should be returned (whatever the current value is)
assert "view_distance" in result
print(f"View distance after focus: {result['view_distance']}")
def test_focus_view_all_axis_alignments(self, real_blender_connection):
"""
Feature: Verify all axis alignments work.
"""
test_cases = [
("FRONT", (0, 0, 0)),
("BACK", (1, 1, 1)),
("LEFT", (-1, 0, 0)),
("RIGHT", (1, 0, 0)),
("TOP", (0, 0, 1)),
("BOTTOM", (0, 0, -1)),
]
for axis, coords in test_cases:
response = send_command(real_blender_connection, "focus_view_on_point", {
"x": coords[0],
"y": coords[1],
"z": coords[2],
"distance": 5.0,
"view_axis": axis
})
assert response["status"] == "success", \
f"Failed for axis={axis}, coords={coords}: {response}"
result = response["result"]
target = result["target"]
# Verify coordinates match
assert target["x"] == coords[0], f"X mismatch for {axis}"
assert target["y"] == coords[1], f"Y mismatch for {axis}"
assert target["z"] == coords[2], f"Z mismatch for {axis}"
print(f"Axis {axis} at {coords}: OK")