Kamiar Aminian

74 papers B 2C 3Misc 2Journal 48Unranked 18
YearRankTypeTitle / Venue / Authors
2023 J jnl
Medical Biol. Eng. Comput.
Gaëlle Prigent, Kamiar Aminian, Andrea Cereatti, Francesca Salis, Tecla Bonci, Kirsty Scott, Claudia Mazzà, Lisa Alcock, Silvia Del Din, Eran Gazit, Clint Hansen, Anisoara Paraschiv-Ionescu
2023 J jnl
Sensors
Mina Baniasad, Robin Martin, Xavier Crevoisier, Claude Pichonnaz, Fabio Becce, Kamiar Aminian
2023 B conf
SMC
Yasaman Izadmehr, Kamiar Aminian, Andrés Pérez-Uribe
2022 conf
EMBC
Nathan Kammoun, Salil Apte, Hojjat Karami, Kamiar Aminian
2022 J jnl
Sensors
Sara Pagnamenta, Karoline Blix Grønvik, Kamiar Aminian, Beatrix Vereijken, Anisoara Paraschiv-Ionescu
2022 J jnl
Sensors
Mahdi Hamidi Rad, Vincent Gremeaux-Bader, Fabien Massé, Farzin Dadashi, Kamiar Aminian
2022 conf
EMBC
Gaëlle Prigent, Estelle Barthelet, Kamiar Aminian, Anisoara Paraschiv-Ionescu
2021 J jnl
IEEE Access
Lai Kuan Tham, Noor Azuan Abu Osman, Mouaz Al Kouzbary, Kamiar Aminian
2021 J jnl
Sensors
Marta Francisca Corrà, Arash Atrsaei, Ana Sardoreira, Clint Hansen, Kamiar Aminian, Manuel Correia, Nuno Vila-Chã, Walter Maetzler, Luís Maia
2021 J jnl
Sensors
Gaëlle Prigent, Kamiar Aminian, Tiago Rodrigues, Jean-Marc Vesin, Grégoire P. Millet, Mathieu Falbriard, Frédéric Meyer, Anisoara Paraschiv-Ionescu
2021 J jnl
IEEE J. Biomed. Health Informatics
Arash Atrsaei, Farzin Dadashi, Benoit Mariani, Roman Gonzenbach, Kamiar Aminian
2020 J jnl
IEEE Trans. Biomed. Eng.
Seyed Abdolmajid Yousefsani, Hooman Dejnabadi, Olivier Guyen, Kamiar Aminian
2020 J jnl
Frontiers Digit. Health
Kristin Taraldsen, A. Stefanie Mikolaizak, Andrea B. Maier, Sabato Mellone, Elisabeth Boulton, Kamiar Aminian, Clemens Becker, Lorenzo Chiari, Turid Follestad, Brenda Gannon, Anisoara Paraschiv-Ionescu, Mirjam Pijnappels, Ingvild Saltvedt, Michael Schwenk, Chris J. Todd, Fan B. Yang, Anna Zacchi, Jeanine M. Van Ancum, Beatrix Vereijken, Jorunn L. Helbostad
2020 ed.
IHIET (Lausanne)
Tareq Z. Ahram, Redha Taïar, Vincent Gremeaux-Bader, Kamiar Aminian
2020 J jnl
Sensors
Mathieu Falbriard, Maurice Mohr, Kamiar Aminian
2020 J jnl
IEEE Access
Abolfazl Soltani, Anisoara Paraschiv-Ionescu, Hooman Dejnabadi, Pedro Marques-Vidal, Kamiar Aminian
2020 J jnl
IEEE J. Biomed. Health Informatics
Abolfazl Soltani, Hooman Dejnabadi, Martin Savary, Kamiar Aminian
2020 conf
EMBC
Anisoara Paraschiv-Ionescu, Abolfazl Soltani, Kamiar Aminian
2020 J jnl
Sensors
Mathieu Falbriard, Maurice Mohr, Kamiar Aminian
2019 J jnl
Sensors
Benedikt Fasel, Jörg Spörri, Josef Kröll, Erich Müller, Kamiar Aminian
2019 J jnl
Sensors
Lena Carcreff, Anisoara Paraschiv-Ionescu, Corinna N. Gerber, Christopher J. Newman, Stéphane Armand, Kamiar Aminian
2018 J jnl
Medical Biol. Eng. Comput.
Christopher Moufawad el Achkar, Constanze Lenoble-Hoskovec, Anisoara Paraschiv-Ionescu, Kristof Major, Christophe J. Büla, Kamiar Aminian
2018 J jnl
Sensors
Wei Zhang, Michael Schwenk, Sabato Mellone, Anisoara Paraschiv-Ionescu, Beatrix Vereijken, Mirjam Pijnappels, A. Stefanie Mikolaizak, Elisabeth Boulton, Nini H. Jonkman, Andrea B. Maier, Jochen Klenk, Jorunn L. Helbostad, Kristin Taraldsen, Kamiar Aminian
2018 J jnl
Medical Biol. Eng. Comput.
Arnaud Barré, Kamiar Aminian
2018 conf
IWBBIO (2)
Julien Esseiva, Maurizio Caon, Elena Mugellini, Omar Abou Khaled, Kamiar Aminian
2018 J jnl
Sensors
Wei Zhang, Matthew Smuck, Catherine Legault, Ma A. Ith, Amir Muaremi, Kamiar Aminian
2018 J jnl
IEEE J. Biomed. Health Informatics
Benedikt Fasel, Jörg Spörri, Julien Chardonnens, Josef Kröll, Erich Müller, Kamiar Aminian
2018 conf
EMBC
Wei Zhang, Matthew Smuck, Catherine Legault, Ma A. Ith, Amir Muaremi, Kamiar Aminian
2018 J jnl
Sensors
Lena Carcreff, Corinna N. Gerber, Anisoara Paraschiv-Ionescu, Geraldo De Coulon, Christopher J. Newman, Stéphane Armand, Kamiar Aminian
2017 J jnl
Medical Biol. Eng. Comput.
Benedikt Fasel, Cyntia Duc, Farzin Dadashi, Flavien Bardyn, Martin Savary, Pierre-André Farine, Kamiar Aminian
2017 J jnl
Sensors
Jorunn L. Helbostad, Beatrix Vereijken, Clemens Becker, Chris J. Todd, Kristin Taraldsen, Mirjam Pijnappels, Kamiar Aminian, Sabato Mellone
2016 conf
EMBC
Alan K. Bourke, Jochen Klenk, Lars Schwickert, Kamiar Aminian, Espen A. F. Ihlen, Sabato Mellone, Jorunn L. Helbostad, Lorenzo Chiari, Clemens Becker
2016 conf
Nursing Informatics
Christopher Moufawad el Achkar, Constanze Lenoble-Hoskovec, Kristof Major, Anisoara Paraschiv-Ionescu, Christophe J. Büla, Kamiar Aminian
2016 conf
SiPS
Flavien Bardyn, Martin Savary, S. Grassi, Pierre-André Farine, Benedikt Fasel, Kamiar Aminian
2016 conf
UbiComp Adjunct
Anisoara Paraschiv-Ionescu, Sabato Mellone, Marco Colpo, Alan Bourke, Espen A. F. Ihlen, Christopher Moufawad el Achkar, Lorenzo Chiari, Clemens Becker, Kamiar Aminian
2016 J jnl
Sensors
Christopher Moufawad el Achkar, Constanze Lenoble-Hoskovec, Anisoara Paraschiv-Ionescu, Kristof Major, Christophe J. Büla, Kamiar Aminian
2016 J jnl
Remote. Sens.
Benedikt Fasel, Jörg Spörri, Matthias Gilgien, Geo Boffi, Julien Chardonnens, Erich Müller, Kamiar Aminian
2015 J jnl
Pervasive Mob. Comput.
Farzin Dadashi, Gregoire P. Millet, Kamiar Aminian
2015 J jnl
Sensors
Claude Pichonnaz, Cyntia Duc, Nigel Gleeson, Céline Ancey, Hervé Jaccard, Estelle Lécureux, Alain Farron, Brigitte M. Jolles, Kamiar Aminian
2015 conf
EMBC
Alan K. Bourke, Jochen Klenk, Lars Schwickert, Kamiar Aminian, Espen A. F. Ihlen, Jorunn L. Helbostad, Lorenzo Chiari, Clemens Becker
2014 J jnl
Sensors
David Forchelet, Matteo Simoncini, Arash Arami, Arnaud Bertsch, Eric Meurville, Kamiar Aminian, Peter Ryser, Philippe Renaud
2014 Misc conf
UbiComp
Kamiar Aminian, Farzin Dadashi, Benoit Mariani, Constanze Lenoble-Hoskovec, Brigitte Santos-Eggimann, Christophe J. Büla
2014 J jnl
Sensors
Farzin Dadashi, Benoit Mariani, Stephane Rochat, Christophe J. Büla, Brigitte Santos-Eggimann, Kamiar Aminian
2014 conf
BioCAS
Arash Arami, Kamiar Aminian, David Forchelet, Philippe Renaud
2014 J jnl
Sensors
Ulrich Lindemann, Wiebren Zijlstra, Kamiar Aminian, Sebastien F. M. Chastin, Eling D. de Bruin, Jorunn L. Helbostad, Johannes B. J. Bussmann
2013 C conf
BSN
Farzin Dadashi, Arash Arami, Florent Crettenand, Gregoire P. Millet, John Komar, Ludovic Seifert, Kamiar Aminian
2013 J jnl
IEEE Trans. Biomed. Eng.
Arash Salarian, Pierre R. Burkhard, François J. G. Vingerhoets, Brigitte M. Jolles, Kamiar Aminian
2013 J jnl
IEEE Trans. Biomed. Eng.
Arash Arami, A. Vallet, Kamiar Aminian
2013 conf
BODYNETS
Fabien Massé, Alan Bourke, Anisoara Paraschiv-Ionescu, Kamiar Aminian
2013 C conf
BSN
Arash Arami, Arnaud Barré, Roderik Berthelin, Kamiar Aminian
2013 J jnl
IEEE Trans Autom. Sci. Eng.
Arash Arami, Matteo Simoncini, Oguz Atasoy, Shafqat Ali, Willyan Hasenkamp, Arnaud Bertsch, Eric Meurville, Steve Tanner, Philippe Renaud, Catherine Dehollain, Pierre-André Farine, Brigitte M. Jolles, Kamiar Aminian, Peter Ryser
2013 J jnl
IEEE Trans. Biomed. Eng.
Benoit Mariani, Mayté Castro Jiménez, François J. G. Vingerhoets, Kamiar Aminian
2013 conf
PervasiveHealth
Christopher Moufawad el Achkar, Fabien Massé, Arash Arami, Kamiar Aminian
2013 J jnl
IEEE Trans. Biomed. Eng.
Arnaud Barré, Jean-Philippe Thiran, Brigitte M. Jolles, Nicolas Theumann, Kamiar Aminian
2013 C conf
BSN
Farzin Dadashi, Kamiar Aminian, Florent Crettenand, Gregoire P. Millet
2012 conf
MobiHealth
Steve Tanner, Shafqat Ali, Mirjana Banjevic, Arash Arami, Kamiar Aminian, Willyan Hasenkamp, Arnaud Bertsch, Philippe Renaud, Pierre-André Farine
2012 J jnl
Sensors
Farzin Dadashi, Florent Crettenand, Grégoire P. Millet, Kamiar Aminian
2012 J jnl
IEEE Trans. Biomed. Eng.
Benoit Mariani, Stephane Rochat, Christophe J. Büla, Kamiar Aminian
2011 conf
EMBC
Kamiar Aminian, Benoit Mariani, Anisoara Paraschiv-Ionescu, Constanze Hoskovec, Christophe J. Büla, J. Penders, Carlo Tacconi, Fiorella Marcellini
2011 conf
CASE
Arash Arami, Matteo Simoncini, Oguz Atasoy, Willyan Hasenkamp, Shafqat Ali, Arnaud Bertsch, Eric Meurville, Steve Tanner, Hooman Dejnabadi, Vincent Leclercq, Philippe Renaud, Catherine Dehollain, Pierre-André Farine, Brigitte M. Jolles, Kamiar Aminian, Peter Ryser
2009 J jnl
Medical Biol. Eng. Comput.
Brian Coley, Brigitte M. Jolles, Alain Farron, Kamiar Aminian
2008 J jnl
IEEE Trans. Biomed. Eng.
Hooman Dejnabadi, Brigitte M. Jolles, Kamiar Aminian
2008 B conf
Image Processing
Dominique Zosso, Benoît Le Callennec, Meritxell Bach Cuadra, Kamiar Aminian, Brigitte M. Jolles, Jean-Philippe Thiran
2007 J jnl
IEEE Trans. Biomed. Eng.
Arash Salarian, Heike Russmann, François J. G. Vingerhoets, Pierre R. Burkhard, Kamiar Aminian
2007 J jnl
IEEE Trans. Biomed. Eng.
Arash Salarian, Heike Russmann, Christian Wider, Pierre R. Burkhard, François J. G. Vingerhoets, Kamiar Aminian
2006 J jnl
IEEE Trans. Biomed. Eng.
Hooman Dejnabadi, Brigitte M. Jolles, Emilio Casanova, Pascal Fua, Kamiar Aminian
2005 J jnl
IEEE Trans. Biomed. Eng.
Hooman Dejnabadi, Brigitte M. Jolles, Kamiar Aminian
2004 J jnl
Comput. Animat. Virtual Worlds
Kamiar Aminian, Bijan Najafi
2004 J jnl
IEEE Trans. Biomed. Eng.
Arash Salarian, Heike Russmann, François J. G. Vingerhoets, Catherine Dehollain, Yves Blanc, Pierre R. Burkhard, Kamiar Aminian
2003 J jnl
IEEE Trans. Biomed. Eng.
Bijan Najafi, Kamiar Aminian, Anisoara Paraschiv-Ionescu, François Loew, Christophe J. Büla, Philippe A. Robert
2002 J jnl
IEEE Trans. Biomed. Eng.
Bijan Najafi, Kamiar Aminian, François Loew, Yves Blanc, Philippe A. Robert
2002 Misc conf
ICASSP
Anisoara Paraschiv-Ionescu, Christian Jutten, Kamiar Aminian, Bijan Najafi, Philippe A. Robert
2002 conf
ISCAS (1)
Anisoara Paraschiv-Ionescu, Christian Jutten, Kamiar Aminian, Bijan Najafi, Philippe A. Robert
1998 conf
CAPTECH
Kamiar Aminian, Eduardo de Andrés, Karen Rezakhanlou, Carlo Fritsch, Y. Schutz, Michèle Depairon, Pierre-François Leyvraz, Philippe A. Robert
tests/unit/test_database_exporters.py
← Index tests/unit/test_database_exporters.py python
"""
Unit tests for database exporters.
"""
import pytest
import json
from dataclasses import dataclass, asdict
from datetime import datetime, timezone
from unittest.mock import Mock, patch, MagicMock

pytestmark = [pytest.mark.unit, pytest.mark.exporters]


# ============================================================================
# Sample Dataclass for Testing
# ============================================================================

@dataclass
class SampleData:
    """Sample dataclass for export testing."""
    sha256: str = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    name: str = "test_sample"
    value: int = 42
    _id: str = "test_id"


# ============================================================================
# PrintExporter Tests
# ============================================================================

class TestPrintExporter:
    """Tests for PrintExporter class."""

    def test_initialization(self, mock_logger):
        """Test PrintExporter initialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger

    def test_export_dataclass(self, mock_logger, capsys):
        """Test exporting a dataclass."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        sample = SampleData()

        result = exporter.export(sample)

        assert result is True
        captured = capsys.readouterr()
        assert "test_sample" in captured.out

    def test_export_list_of_dataclasses(self, mock_logger, capsys):
        """Test exporting a list of dataclasses."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        samples = [SampleData(name="sample1"), SampleData(name="sample2")]

        result = exporter.export(samples)

        assert result is True
        captured = capsys.readouterr()
        assert "sample1" in captured.out
        assert "sample2" in captured.out

    def test_export_dict(self, mock_logger, capsys):
        """Test exporting a dictionary."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {"key": "value", "number": 42}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "key" in captured.out
        assert "value" in captured.out

    def test_export_none(self, mock_logger):
        """Test exporting None."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export(None)

        assert result is True

    def test_export_empty_list(self, mock_logger):
        """Test exporting empty list."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")

        result = exporter.export([])

        assert result is True


# ============================================================================
# ElasticsearchExporter Tests
# ============================================================================

class TestElasticsearchExporter:
    """Tests for ElasticsearchExporter class."""

    def test_initialization(self, mock_logger):
        """Test ElasticsearchExporter initialization."""
        with patch('redb.settings.get_elasticsearch_client') as mock_client:
            mock_client.return_value = Mock()
            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")

            assert exporter.index_prefix == "test_index"
            assert exporter.log is mock_logger
            assert exporter.client is not None

    def test_export_dataclass(self, mock_logger):
        """Test exporting a dataclass to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True
            mock_client.index.assert_called()

    def test_export_list(self, mock_logger):
        """Test exporting a list to Elasticsearch."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            samples = [SampleData(name="sample1"), SampleData(name="sample2")]

            result = exporter.export(
                samples,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": "test_hash"}
            )

            assert result is True
            # Should be called twice (once per sample)
            assert mock_client.index.call_count == 2

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_client.index.side_effect = Exception("Connection failed")
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData()

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is False
            mock_logger.error.assert_called()

    def test_export_with_custom_id(self, mock_logger):
        """Test exporting with custom _id field."""
        with patch('redb.settings.get_elasticsearch_client') as mock_get_client:
            mock_client = Mock()
            mock_get_client.return_value = mock_client

            from redb.extractors.database_exporters import ElasticsearchExporter

            exporter = ElasticsearchExporter(mock_logger, "test_index")
            sample = SampleData(_id="custom_id")

            result = exporter.export(
                sample,
                index="test_index",
                tag="test_tag",
                hashes={"sha256": sample.sha256}
            )

            assert result is True


# ============================================================================
# ClickHouseExporter Tests
# ============================================================================

class TestClickHouseExporter:
    """Tests for ClickHouseExporter class."""

    def test_initialization(self, mock_logger):
        """Test ClickHouseExporter initialization."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        assert exporter.index_prefix == "test_index"
        assert exporter.log is mock_logger
        assert exporter.client is mock_client

    def test_export_tuple_data(self, mock_logger):
        """Test exporting tuple data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is True

    def test_export_multi_table(self, mock_logger):
        """Test exporting multi-table data to ClickHouse."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table1',
                    'data': [["hash123", "sample.exe"]],
                    'column_names': ["sha256", "name"],
                    'column_type_names': ["String", "String"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_export_failure(self, mock_logger):
        """Test handling export failure."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.side_effect = Exception("Connection failed")
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names),
                table="test_table"
            )

            assert result is False

    def test_export_missing_table(self, mock_logger):
        """Test export without table name raises error."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = [["hash123", "sample.exe", 1024]]
            column_names = ["sha256", "name", "size"]
            column_type_names = ["String", "String", "UInt64"]

            result = exporter.export(
                (data, column_names, column_type_names)
                # Missing table parameter
            )

            assert result is False

    def test_get_client(self, mock_logger):
        """Test get_client method."""
        from redb.extractors.database_exporters import ClickHouseExporter

        mock_client = Mock()
        exporter = ClickHouseExporter(mock_logger, "test_index", client=mock_client)

        result = exporter.get_client()

        assert result is mock_client

    def test_get_client_creates_new(self, mock_logger):
        """Test get_client creates new client if none exists."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_new_client = Mock()
            mock_create.return_value = mock_new_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            result = exporter.get_client()

            assert result is mock_new_client


# ============================================================================
# DatabaseExporter Abstract Base Class Tests
# ============================================================================

class TestDatabaseExporter:
    """Tests for DatabaseExporter abstract base class."""

    def test_cannot_instantiate_abstract(self):
        """Test that DatabaseExporter cannot be instantiated directly."""
        from redb.extractors.database_exporters import DatabaseExporter

        with pytest.raises(TypeError):
            DatabaseExporter()

    def test_subclass_must_implement_export(self):
        """Test that subclasses must implement export method."""
        from redb.extractors.database_exporters import DatabaseExporter

        # Define incomplete subclass
        class IncompleteExporter(DatabaseExporter):
            pass

        with pytest.raises(TypeError):
            IncompleteExporter()


# ============================================================================
# Null/Edge Case Tests
# ============================================================================

class TestExporterEdgeCases:
    """Tests for edge cases in exporters."""

    def test_print_exporter_with_complex_nested_data(self, mock_logger, capsys):
        """Test PrintExporter with complex nested data."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        data = {
            "level1": {
                "level2": {
                    "level3": [1, 2, 3]
                }
            },
            "array": [{"a": 1}, {"b": 2}]
        }

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "level1" in captured.out

    def test_clickhouse_null_handling(self, mock_logger):
        """Test ClickHouse exporter handles null values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            # Multi-table data with null values
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [[None, "sample.exe", None]],
                    'column_names': ["sha256", "name", "size"],
                    'column_type_names': ["Nullable(String)", "String", "Nullable(UInt64)"]
                }
            }

            result = exporter.export(data)

            # Should handle nulls appropriately
            assert result is True

    def test_clickhouse_array_handling(self, mock_logger):
        """Test ClickHouse exporter handles array types."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", ["tag1", "tag2"]]],
                    'column_names': ["sha256", "tags"],
                    'column_type_names': ["String", "Array(String)"]
                }
            }

            result = exporter.export(data)

            assert result is True


# ============================================================================
# Type Conversion Tests
# ============================================================================

class TestExporterTypeConversions:
    """Tests for type conversions in exporters."""

    def test_clickhouse_datetime_handling(self, mock_logger):
        """Test ClickHouse exporter handles datetime values."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_client.insert.return_value = True
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            now = datetime.now(timezone.utc)
            data = {
                'multi_table': True,
                'table1': {
                    'table': 'test_table',
                    'data': [["hash", now]],
                    'column_names': ["sha256", "timestamp"],
                    'column_type_names': ["String", "DateTime64(3, 'UTC')"]
                }
            }

            result = exporter.export(data)

            assert result is True

    def test_print_exporter_datetime_serialization(self, mock_logger, capsys):
        """Test PrintExporter handles datetime serialization."""
        from redb.extractors.database_exporters import PrintExporter

        exporter = PrintExporter(mock_logger, "test_index")
        now = datetime.now(timezone.utc)
        data = {"timestamp": now, "name": "test"}

        result = exporter.export(data)

        assert result is True
        captured = capsys.readouterr()
        assert "timestamp" in captured.out


# ============================================================================
# Connection Context Manager Tests
# ============================================================================

class TestClickHouseConnectionManager:
    """Tests for ClickHouse connection context manager."""

    def test_clickhouse_connection_context(self, mock_logger):
        """Test clickhouse_connection context manager."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            with exporter.clickhouse_connection() as client:
                assert client is mock_client

            # Client should be closed after context exits
            mock_client.close.assert_called()

    def test_clickhouse_connection_close_on_error(self, mock_logger):
        """Test client is closed even if operation fails."""
        with patch('redb.settings.create_clickhouse_client') as mock_create:
            mock_client = Mock()
            mock_create.return_value = mock_client

            from redb.extractors.database_exporters import ClickHouseExporter

            exporter = ClickHouseExporter(mock_logger, "test_index")

            try:
                with exporter.clickhouse_connection() as client:
                    raise ValueError("Test error")
            except ValueError:
                pass

            # Client should still be closed
            mock_client.close.assert_called()