Co-Study4Grid / expert_backend /tests /test_direct_file_loading.py
github-actions[bot]
Deploy 7688ef1
13d4e44
Raw
History Blame Contribute Delete
4.81 kB
# Copyright (c) 2025-2026, RTE (https://www.rte-france.com)
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of Co-Study4Grid a Power Grid Study tool Assistant Interface to help solve contigencies for a grid state under study.
import unittest
from unittest.mock import MagicMock, patch, mock_open
from pathlib import Path
from expert_backend.services.recommender_service import RecommenderService
from expert_backend.main import ConfigRequest
from expert_op4grid_recommender import config as recommender_config
class TestDirectFileLoading(unittest.TestCase):
def setUp(self):
self.service = RecommenderService()
self.original_config = {
'ENV_FOLDER': recommender_config.ENV_FOLDER,
'ENV_NAME': recommender_config.ENV_NAME,
'ENV_PATH': recommender_config.ENV_PATH,
'ACTION_FILE_PATH': recommender_config.ACTION_FILE_PATH,
}
def tearDown(self):
recommender_config.ENV_FOLDER = self.original_config['ENV_FOLDER']
recommender_config.ENV_NAME = self.original_config['ENV_NAME']
recommender_config.ENV_PATH = self.original_config['ENV_PATH']
recommender_config.ACTION_FILE_PATH = self.original_config['ACTION_FILE_PATH']
@patch("expert_backend.services.recommender_service.load_actions")
@patch("expert_backend.services.recommender_service.enrich_actions_lazy")
@patch("expert_backend.services.network_service.network_service")
@patch("builtins.open", new_callable=mock_open)
def test_update_config_with_xiidm_file(self, mock_file, mock_ns, mock_enrich, mock_load):
# Setup mock load_actions to return a real dict to avoid serialization issues
mock_load.return_value = {"actions": {}}
# Scenario: user provides a .xiidm file as network_path
# Note: Frontend sends absolute path for network_path when a file is selected
network_path = "/path/to/data/my_grid.xiidm"
action_path = "/path/to/actions.json"
settings = ConfigRequest(
network_path=network_path,
action_file_path=action_path,
monitoring_factor=0.95
)
# Mock Path.exists to return True for the files
with patch.object(Path, "exists", return_value=True), \
patch.object(Path, "is_file", side_effect=lambda self: self.name == "my_grid.xiidm" or self.name == "actions.json"), \
patch.object(Path, "is_dir", side_effect=lambda self: self.name == "data"):
self.service.update_config(settings)
# Verify recommender config was updated correctly.
# Convert to string for comparison as recommender_config might store Path or string
self.assertEqual(str(recommender_config.ENV_FOLDER), str(Path(network_path).parent))
self.assertEqual(recommender_config.ENV_NAME, "my_grid.xiidm")
self.assertEqual(str(recommender_config.ENV_PATH), network_path)
self.assertEqual(str(recommender_config.ACTION_FILE_PATH), action_path)
@patch("pypowsybl.network.load")
def test_get_base_network_with_file_path(self, mock_load):
service = RecommenderService()
# Setup scenario where ENV_PATH is a direct file
network_path = "/path/to/data/grid.xiidm"
direct_path = Path(network_path)
recommender_config.ENV_PATH = direct_path
mock_net = MagicMock()
mock_load.return_value = mock_net
# Force the fallback path by making `network_service.network` None.
# Normally `_get_base_network` prefers the network already loaded
# by network_service (mutualisation — see recommender_service.py).
# This test exercises the standalone pypowsybl load path for
# callers that bypass /api/config.
from expert_backend.services.network_service import network_service
saved_network = network_service.network
network_service.network = None
try:
with patch.object(Path, "exists", return_value=True), \
patch.object(Path, "is_dir", return_value=False):
# Call the internal method (no arguments)
n = service._get_base_network()
# Verify pypowsybl.network.load was called with the direct file path
mock_load.assert_called_once_with(str(direct_path))
self.assertEqual(n, mock_net)
finally:
network_service.network = saved_network
if __name__ == "__main__":
unittest.main()