Victor M. Ruiz Penichet

96 papers B 1C 2Misc 1Journal 28Unranked 55
YearRankTypeTitle / Venue / Authors
2025 J jnl
Univers. Access Inf. Soc.
Iván Durango, Victor M. Ruiz Penichet, José A. Gallud
2025 J jnl
Int. J. Data Sci. Anal.
Iván Durango, José A. Gallud, Victor M. Ruiz Penichet
2024 J jnl
CoRR
Iván Durango, José A. Gallud, Victor M. Ruiz Penichet
2023 conf
Interacción
María González López, Félix Albertos Marco, Lucía Polo Martínez, Belén Luna Lorente, Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud
2023 J jnl
Multim. Tools Appl.
Jose Maria Garcia-Garcia, María Dolores Lozano, Victor M. Ruiz Penichet, Effie Lai-Chong Law
2023 J jnl
Proc. ACM Hum. Comput. Interact.
Axel Carayon, Juan Enrique Garrido, Célia Martinie, Philippe A. Palanque, Eric Barboni, María Dolores Lozano, Victor M. Ruiz Penichet
2023 conf
Interacción
Javier Jiménez Honrado, Gabriel Sebastián Rivera, José A. Gallud, Victor M. Ruiz Penichet
2023 J jnl
Univers. Access Inf. Soc.
José A. Gallud, Mónica A. Carreño, Ricardo Tesoriero, Andrés Sandoval, María Dolores Lozano, Israel Durán-Encinas, Victor M. Ruiz Penichet, Rafael Cosio-Castro
2022 J jnl
Multim. Tools Appl.
Victor M. Ruiz Penichet, María Dolores Lozano, Juan Enrique Garrido, Félix Albertos Marco, Raymond R. Bond, Maurice D. Mulvenna
2022 conf
Interacción
Pablo Córcoles Molina, Victor M. Ruiz Penichet, María Dolores Lozano, Juan Enrique Garrido, Jose Maria Garcia-Garcia, Félix Albertos Marco
2022 J jnl
IEEE Access
José A. Gallud, Ricardo Tesoriero, María Dolores Lozano, Victor M. Ruiz Penichet, Habib M. Fardoun
2022 J jnl
Univers. Access Inf. Soc.
Jose Maria Garcia-Garcia, Victor M. Ruiz Penichet, María Dolores Lozano, Anil Fernando
2020 J jnl
Univers. Access Inf. Soc.
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano
2019 conf
Interacción
Jose Maria Garcia-Garcia, María del Mar Cabañero, Victor M. Ruiz Penichet, María Dolores Lozano
2019 J jnl
Univers. Access Inf. Soc.
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano, Alberto Mora Plata, José Antonio Fernández Valls
2018 J jnl
IEEE Access
Félix Albertos Marco, José A. Gallud, Victor M. Ruiz Penichet
2018 conf
Interacción
Alejandro López Cardo, Victor M. Ruiz Penichet, María Dolores Lozano, Juan Enrique Garrido
2018 J jnl
Univers. Access Inf. Soc.
Iván Durango, Alicia Carrascosa, José A. Gallud, Victor M. Ruiz Penichet
2018 J jnl
Mob. Inf. Syst.
Jose Maria Garcia-Garcia, Victor M. Ruiz Penichet, María Dolores Lozano, Juan Enrique Garrido, Effie Lai-Chong Law
2017 J jnl
J. Web Eng.
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud Lázaro, Marco Winckler
2017 ed.
REHAB (Revised Selected Papers)
Habib M. Fardoun, Victor M. Ruiz Penichet, Daniyal M. Alghazzawi, M. Elena de la Guía
2016 conf
ICWE Workshops
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2016 conf
Interacción
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2016 J jnl
IEEE Trans. Learn. Technol.
Elena de la Guía, Vicente López Camacho, Luis Orozco-Barbosa, Victor M. Brea Lujan, Victor M. Ruiz Penichet, María Dolores Lozano Pérez
2016 conf
Interacción
Alberto Mora Plata, Juan Enrique Garrido, José Antonio Fernández Valls, Victor M. Ruiz Penichet, María Dolores Lozano
2016 ed.
REHAB
Habib M. Fardoun, Victor M. Ruiz Penichet, Daniyal M. Alghazzawi, Pedro Gamito
2016 conf
ICWE Workshops
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2015 conf
REHAB
Elena de la Guía, Vicente López, Teresa Olivares, María Dolores Lozano, Victor M. Ruiz Penichet, Luis Orozco-Barbosa
2015 J jnl
Br. J. Educ. Technol.
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2015 conf
Interacción
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet, Luis Orozco-Barbosa, Vicente López
2015 ed.
REHAB
Habib M. Fardoun, Victor M. Ruiz Penichet, Daniyal M. Alghazzawi
2015 conf
REHAB
Félix Albertos Marco, José Antonio Fernández Valls, Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud
2015 ed.
REHAB
Habib M. Fardoun, Pedro Gamito, Victor M. Ruiz Penichet, Daniyal M. Alghazzawi
2015 conf
Interacción
Iván Durango, Alicia Carrascosa, Victor M. Ruiz Penichet, José A. Gallud
2015 conf
Interacción
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2015 conf
REHAB
José Antonio Fernández Valls, Victor M. Ruiz Penichet, María Dolores Lozano
2014 conf
DUI@ICWE
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2014 conf
Interacción
José Antonio Fernández Valls, Victor M. Ruiz Penichet, María Dolores Lozano, Juan Enrique Garrido, Carlos Gimena Bello
2014 B conf
AVI
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano, Aaron J. Quigley, Per Ola Kristensson
2014 conf
PervasiveHealth
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano, Per Ola Kristensson, Aaron J. Quigley
2014 conf
DUI@ICWE
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2014 conf
PervasiveHealth
José Antonio Fernández Valls, Victor M. Ruiz Penichet, María Dolores Lozano
2013 Misc conf
EICS
María Dolores Lozano, José A. Gallud, Ricardo Tesoriero, Victor M. Ruiz Penichet, Jean Vanderdonckt, Habib Fardoun
2013 conf
ICWE Workshops
Félix Albertos Marco, José A. Gallud, Victor M. Ruiz Penichet, Marco Winckler
2013 J jnl
J. Univers. Comput. Sci.
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano
2013 J jnl
J. Univers. Comput. Sci.
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano, José Antonio Fernández Valls
2013 conf
PervasiveHealth
Juan Enrique Garrido, Irma Marset, Victor M. Ruiz Penichet, María Dolores Lozano
2013 conf
PervasiveHealth
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2013 J jnl
J. Univers. Comput. Sci.
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2013 conf
HCI (26)
Pedro González Villanueva, Félix Albertos Marco, Ricardo Tesoriero, José A. Gallud, Antonio Hernández, Victor M. Ruiz Penichet
2013 book
María Dolores Lozano, José A. Gallud, Ricardo Tesoriero, Victor M. Ruiz Penichet
2013 conf
DUI@EICS
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2013 conf
DUI@EICS
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2013 conf
CHI Extended Abstracts
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2012 C conf
FedCSIS
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2012 J jnl
Int. J. Hum. Comput. Interact.
Elena de la Guía, Victor M. Ruiz Penichet, Juan Enrique Garrido, Félix Albertos Marco
2012 C conf
FedCSIS
Juan Enrique Garrido Navarro, Victor M. Ruiz Penichet, María Dolores Lozano Pérez, Luis Antonio Sánchez
2012 conf
ebTEL
Habib M. Fardoun, Daniyal M. Alghazzawi, Sebastián Romero López, Victor M. Ruiz Penichet, José A. Gallud
2012 conf
IWAAL
Juan Enrique Garrido Navarro, Victor M. Ruiz Penichet, María Dolores Lozano
2012 conf
UCAmI
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2012 conf
CHI Extended Abstracts
Ricardo Tesoriero, María Dolores Lozano, Jean Vanderdonckt, José A. Gallud, Victor M. Ruiz Penichet
2011 ch.
Distributed User Interfaces
Elena de la Guía, María Dolores Lozano, Victor M. Ruiz Penichet
2011 conf
HCI (8)
Giulio Mori, Maria Claudia Buzzi, Marina Buzzi, Barbara Leporini, Victor M. Ruiz Penichet
2011 book
José A. Gallud, Ricardo Tesoriero, Victor M. Ruiz Penichet
2011 conf
CHI Extended Abstracts
José A. Gallud, Ricardo Tesoriero, Jean Vanderdonckt, María Dolores Lozano, Victor M. Ruiz Penichet, Federico Botella
2011 ch.
Distributed User Interfaces
Félix Albertos Marco, Victor M. Ruiz Penichet, José A. Gallud
2011 ch.
Distributed User Interfaces
Juan Enrique Garrido, Victor M. Ruiz Penichet, María Dolores Lozano
2010 conf
ICCHP (1)
Maria Claudia Buzzi, Marina Buzzi, Barbara Leporini, Giulio Mori, Victor M. Ruiz Penichet
2010 J jnl
J. Univers. Comput. Sci.
Ricardo Tesoriero, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2010 conf
Mobile HCI
Elena de la Guía, José A. Gallud, Ricardo Tesoriero, María Dolores Lozano, Victor M. Ruiz Penichet
2010 J jnl
Expert Syst. Appl.
Ricardo Tesoriero, R. Tebar, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2010 conf
ADNTIIC
Giulio Mori, Maria Claudia Buzzi, Marina Buzzi, Barbara Leporini, Victor M. Ruiz Penichet
2010 J jnl
J. Syst. Softw.
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2009 conf
HCI (10)
María Paula González, Victor M. Ruiz Penichet, Guillermo Ricardo Simari, Ricardo Tesoriero
2009 conf
HCI (4)
Ricardo Tesoriero, Habib Fardoun, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2009 J jnl
IEEE Trans. Consumer Electron.
Ricardo Tesoriero, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2009 J jnl
Adv. Eng. Softw.
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2008 conf
ICEIS (5)
Victor M. Ruiz Penichet, Manuel Tobarra, María Dolores Lozano, José A. Gallud, Francisco Montero Simarro
2008 conf
ICAS
Ricardo Tesoriero, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2008 conf
CADUI
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2008 conf
ICCS (3)
Victor M. Ruiz Penichet, José A. Gallud, Ricardo Tesoriero, María Dolores Lozano
2008 J jnl
J. Univers. Comput. Sci.
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero, María Luisa Rodríguez, José Luis Garrido, Manuel Noguera, María Visitación Hurtado
2008 J jnl
IEEE Trans. Consumer Electron.
Ricardo Tesoriero, José A. Gallud, María Dolores Lozano, Victor M. Ruiz Penichet
2007 conf
WEBIST (1)
María Dolores Lozano, Ricardo Tesoriero, José A. Gallud, Victor M. Ruiz Penichet
2007 conf
JISBD
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2007 conf
WEBIST (2)
Ricardo Tesoriero, María Dolores Lozano, José A. Gallud, Victor M. Ruiz Penichet
2007 conf
Interacción (selected papers)
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2007 conf
TAMODIA
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud, Ricardo Tesoriero
2007 conf
HCI (2)
José A. Gallud, María Dolores Lozano, Ricardo Tesoriero, Victor M. Ruiz Penichet
2006 conf
VODCA@FOSAD
Victor M. Ruiz Penichet, Ismael Marín, José A. Gallud, María Dolores Lozano, Ricardo Tesoriero
2006 conf
DSV-IS
Victor M. Ruiz Penichet, Fabio Paternò, José A. Gallud, María Dolores Lozano
2006 conf
LA-WEB
Victor M. Ruiz Penichet, María Dolores Lozano, José A. Gallud
2006 conf
DSV-IS
Stéphane Chatty, José Creissac Campos, María Paula González, Sophie Lepreux, Erik G. Nilsson, Victor M. Ruiz Penichet, Mónica Sara Santos, Jan Van den Bergh
2006 conf
CRIWG
Victor M. Ruiz Penichet, José A. Gallud, María Dolores Lozano, Manuel Tobarra
2005 conf
EGOV (Workshops and Posters)
Victor M. Ruiz Penichet, José A. Gallud, Antonio Fernández-Caballero, María Dolores Lozano
2004 conf
DEXA Workshops
Victor M. Ruiz Penichet, José A. Gallud, M. L. González, Pascual González
tests/unit/test_dataclasses.py
← Index tests/unit/test_dataclasses.py python
"""
Unit tests for redb.models.dataclasses.

These tests verify construction, field defaults, and type expectations for
every dataclass in the module (excluding Mach-O dataclasses, which are
covered by test_macho_dataclasses.py).
"""
import pytest
from dataclasses import asdict, fields

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


# ============================================================================
# Hash / Hashes
# ============================================================================

class TestHashDataclass:
    """Tests for the Hash dataclass."""

    def test_creation(self):
        from redb.models.dataclasses import Hash

        h = Hash(
            md5="d41d8cd98f00b204e9800998ecf8427e",
            sha1="da39a3ee5e6b4b0d3255bfef95601890afd80709",
            sha256="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
        assert h.md5 == "d41d8cd98f00b204e9800998ecf8427e"
        assert h.sha1 == "da39a3ee5e6b4b0d3255bfef95601890afd80709"
        assert h.sha256 == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

    def test_asdict(self):
        from redb.models.dataclasses import Hash

        h = Hash(md5="a", sha1="b", sha256="c")
        d = asdict(h)
        assert d == {"md5": "a", "sha1": "b", "sha256": "c"}


class TestHashesDataclass:
    """Tests for the Hashes dataclass."""

    def test_required_fields(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(
            md5="md5val",
            sha1="sha1val",
            sha256="sha256val",
            ssdeep_hash="ssdeep",
            tlsh_hash="tlsh",
        )
        assert h.md5 == "md5val"
        assert h.ssdeep_hash == "ssdeep"

    def test_optional_pe_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.authentihash is None
        assert h.imphash is None
        assert h.richhash is None
        assert h.richpe_hash is None
        assert h.richpv_hash is None
        assert h.richpv_hash_sorted is None
        assert h.typerefhash is None
        assert h.impfuzzy is None

    def test_optional_elf_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.import_hash is None
        assert h.export_hash is None
        assert h.section_hash is None
        assert h.symbol_hash is None
        assert h.dynamic_hash is None

    def test_optional_macho_fields_default_none(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e")
        assert h.macho_dylib_hash is None
        assert h.macho_import_hash is None
        assert h.macho_export_hash is None
        assert h.macho_entitlement_hash is None
        assert h.macho_symhash is None

    def test_macho_fields_settable(self):
        from redb.models.dataclasses import Hashes

        h = Hashes(
            md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e",
            macho_dylib_hash="dylib_h",
            macho_import_hash="import_h",
            macho_export_hash="export_h",
            macho_entitlement_hash="ent_h",
            macho_symhash="sym_h",
        )
        assert h.macho_dylib_hash == "dylib_h"
        assert h.macho_import_hash == "import_h"
        assert h.macho_export_hash == "export_h"
        assert h.macho_entitlement_hash == "ent_h"
        assert h.macho_symhash == "sym_h"


# ============================================================================
# BasicProperties
# ============================================================================

class TestBasicPropertiesDataclass:
    """Tests for the BasicProperties dataclass."""

    def test_required_fields(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="test.exe",
            sample_name="test.exe",
            filesize=1024,
            filetype="PE32",
            filetype_mime="application/x-dosexec",
            filetype_magika="pebin",
            file_entropy=6.5,
        )
        assert bp.filename == "test.exe"
        assert bp.filesize == 1024
        assert bp.file_entropy == 6.5

    def test_optional_fields_default_none(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="x", sample_name="x", filesize=0,
            filetype="t", filetype_mime="m", filetype_magika="k", file_entropy=0.0,
        )
        assert bp.is_packed is None
        assert bp.is_fat is None
        assert bp.child_sha256 is None
        assert bp.child_architecture is None
        assert bp.child_filetype is None

    def test_fat_fields(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="universal.app",
            sample_name="universal.app",
            filesize=2048,
            filetype="Mach-O universal",
            filetype_mime="application/x-mach-binary",
            filetype_magika="macho",
            file_entropy=7.2,
            is_fat=True,
            child_sha256=["hash1", "hash2"],
            child_architecture=["x86_64", "arm64"],
            child_filetype=["macho", "macho"],
        )
        assert bp.is_fat is True
        assert len(bp.child_sha256) == 2
        assert bp.child_architecture == ["x86_64", "arm64"]

    def test_asdict_roundtrip(self):
        from redb.models.dataclasses import BasicProperties

        bp = BasicProperties(
            filename="f", sample_name="s", filesize=10,
            filetype="t", filetype_mime="m", filetype_magika="k", file_entropy=1.0,
        )
        d = asdict(bp)
        assert d["filename"] == "f"
        assert d["is_fat"] is None


# ============================================================================
# DIEinfo / CAPA
# ============================================================================

class TestDIEinfoDataclass:
    def test_creation(self):
        from redb.models.dataclasses import DIEinfo

        d = DIEinfo(die_full_dump="dump_text")
        assert d.die_full_dump == "dump_text"
        assert d.die_info == {}

    def test_with_info(self):
        from redb.models.dataclasses import DIEinfo

        d = DIEinfo(die_full_dump="x", die_info={"packer": "UPX"})
        assert d.die_info["packer"] == "UPX"


class TestCAPADataclass:
    def test_creation(self):
        from redb.models.dataclasses import CAPA

        c = CAPA(
            capa_dump="dump",
            capabilities=["cap1"],
            namespaces=["ns1"],
            attack_dump="attack",
            tactics=["TA0001"],
            techniques=["T1059"],
            techniques_id=["T1059.001"],
            mbc_dump="mbc",
            mbc_objectives=["obj1"],
            mbc_behaviors=["beh1"],
            mbc_behaviors_id=["B0001"],
        )
        assert c.capa_dump == "dump"
        assert "cap1" in c.capabilities
        assert "TA0001" in c.tactics


# ============================================================================
# Malcontent
# ============================================================================

class TestMalcontentDataclass:
    def test_creation(self):
        from redb.models.dataclasses import Malcontent

        m = Malcontent(
            malcontent_dump='{"RiskScore": 2}',
            version="malcontent v1.0.0",
            risk_score=2,
            risk_level="MEDIUM"
        )
        assert m.malcontent_dump == '{"RiskScore": 2}'
        assert m.version == "malcontent v1.0.0"
        assert m.risk_score == 2
        assert m.risk_level == "MEDIUM"

    def test_with_json_content(self):
        from redb.models.dataclasses import Malcontent
        import json

        # Now stores unwrapped content (without Files/<path> wrapper)
        file_content = {
            "RiskScore": 3,
            "RiskLevel": "HIGH",
            "IsMalcontent": True,
            "Behaviors": [
                {"RuleName": "exec/shell", "RiskLevel": "HIGH", "Description": "executes shell commands"}
            ]
        }
        m = Malcontent(
            malcontent_dump=json.dumps(file_content),
            version="v0.5.0",
            risk_score=3,
            risk_level="HIGH"
        )
        parsed = json.loads(m.malcontent_dump)
        assert parsed["RiskLevel"] == "HIGH"
        assert parsed["Behaviors"][0]["RuleName"] == "exec/shell"

    def test_asdict(self):
        from redb.models.dataclasses import Malcontent
        from dataclasses import asdict

        m = Malcontent(malcontent_dump="{}", version="v1", risk_score=0, risk_level="")
        d = asdict(m)
        assert d == {"malcontent_dump": "{}", "version": "v1", "risk_score": 0, "risk_level": ""}


# ============================================================================
# String
# ============================================================================

class TestStringDataclass:
    def test_creation(self):
        from redb.models.dataclasses import String

        s = String(string="hello", string_length=5, string_entropy=2.3, string_frequency=10)
        assert s.string == "hello"
        assert s.md5 == []
        assert s.sha1 == []
        assert s.sha256 == []

    def test_with_hashes(self):
        from redb.models.dataclasses import String

        s = String(
            string="test", string_length=4, string_entropy=2.0, string_frequency=1,
            md5=["abc"], sha256=["def"],
        )
        assert s.md5 == ["abc"]
        assert s.sha256 == ["def"]


# ============================================================================
# PE Dataclasses
# ============================================================================

class TestPEDataclass:
    def test_required_fields(self):
        from redb.models.dataclasses import PE

        pe = PE(
            dos_header="dos", nt_header="nt", optional_header="opt",
            file_header="fh", magic="0x10b", entry_point="0x1000",
            major_linker_version=14, minor_linker_version=0,
            target_machine="I386", architecture="x86",
            compilation_time=1609459200, compilation_time_utc="2021-01-01T00:00:00",
            is_dotnet=False, is_signed=False, has_overlay=False,
            number_of_sections=4, number_of_imports=10,
            number_of_exports=0, number_of_resources=2,
            type="EXE",
        )
        assert pe.architecture == "x86"
        assert pe.type == "EXE"

    def test_optional_fields_default_none(self):
        from redb.models.dataclasses import PE

        pe = PE(
            dos_header="d", nt_header="n", optional_header="o",
            file_header="f", magic="m", entry_point="e",
            major_linker_version=0, minor_linker_version=0,
            target_machine="t", architecture="a",
            compilation_time=0, compilation_time_utc="",
            is_dotnet=False, is_signed=False, has_overlay=False,
            number_of_sections=0, number_of_imports=0,
            number_of_exports=0, number_of_resources=0,
            type="DLL",
        )
        assert pe.dbg_struct is None
        assert pe.tls_struct is None
        assert pe.rich_header_dump is None
        assert pe.version_info is None


class TestPEImportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEImport

        pi = PEImport(pe_imports_total=5)
        assert pi.pe_imports_total == 5
        assert pi.pe_import_libraryName is None
        assert pi.pe_import_functions is None


class TestPESectionDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PESection

        ps = PESection(
            _id="sec_id", section_entropy=6.5, section_sha256="sha",
            section_md5="md5", section_name=".text", section_name_b64=".text",
            section_pointer_to_raw_data="0x400",
            section_size=4096, section_v_addr="0x1000",
            section_v_addr_hex="0x1000", section_v_size=8192,
        )
        assert ps.section_name == ".text"
        assert ps.section_entropy == 6.5


class TestPEResourceDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEResource

        pr = PEResource(
            _id="res_id", resource_type="RT_ICON", resource_entropy=3.5,
            resource_sha256="sha", resource_filetype="image/png",
            resource_magika="png", resource_language="LANG_ENGLISH",
            resource_sub_lang="SUBLANG_DEFAULT",
            resource_rva="0x2000", resource_size=1024,
        )
        assert pr.resource_type == "RT_ICON"


class TestPEOverlayDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEOverlay

        po = PEOverlay(
            _id="ovl_id", overlay_size=512, overlay_entropy=7.9,
            overlay_offset="0x5000", overlay_mimetype="application/octet-stream",
            overlay_type="data", overlay_magika="unknown",
            overlay_sha256="sha", overlay_sha1="sha1", overlay_md5="md5",
        )
        assert po.overlay_size == 512


class TestPESignerDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PESigner

        ps = PESigner(
            signer_serial_number="01", signer_subject="CN=Test",
            signer_issuer="CN=CA", signer_valid_from="2021-01-01",
            signer_valid_to="2025-01-01", signer_thumbprint="aabb",
            signer_algorithm="sha256WithRSAEncryption",
        )
        assert ps.signer_subject == "CN=Test"


class TestPECertificateDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PECertificate

        pc = PECertificate(
            certificate_serial_number="02", certificate_subject="CN=Cert",
            certificate_issuer="CN=CA", certificate_valid_from="2021-01-01",
            certificate_valid_to="2025-01-01", certificate_thumbprint="ccdd",
            certificate_algorithm="sha256",
        )
        assert pc.certificate_serial_number == "02"


class TestPECodeSigningInfoDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PECodeSigningInfo

        cs = PECodeSigningInfo(
            _id="cs_id", signature_verified=True, number_of_certificates=2,
        )
        assert cs.signature_verified is True
        assert cs.x509_certificates is None

    def test_with_certificates(self):
        from redb.models.dataclasses import PECodeSigningInfo

        cs = PECodeSigningInfo(
            _id="cs_id", signature_verified=False, number_of_certificates=0,
            x509_certificates=[{"cn": "test"}],
        )
        assert len(cs.x509_certificates) == 1


class TestPEExtraFindingDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEExtraFinding

        ef = PEExtraFinding(context="anomaly_detection")
        assert ef.context == "anomaly_detection"
        assert ef.finding is None


class TestPEDotNetDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEDotNet

        dn = PEDotNet()
        assert dn.dotnet == {}

    def test_with_data(self):
        from redb.models.dataclasses import PEDotNet

        dn = PEDotNet(dotnet={"runtime": "v4.0.30319"})
        assert dn.dotnet["runtime"] == "v4.0.30319"


class TestDotNetInconsistencyTestsDataclass:
    def test_creation(self):
        from redb.models.dataclasses import DotNetInconsistencyTests

        it = DotNetInconsistencyTests(
            test_dotnet_data_dir_hidden=False,
            test_dotnet_fake_types=True,
            test_dotnet_extra_data=None,
            test_dotnet_invalid_type_ref=False,
            test_dotnet_fake_datastreams=False,
            test_dotnet_extra_module_table=None,
            test_dotnet_extra_assembly_table=False,
            test_dotnet_invalid_strings_stream=False,
            test_dotnet_streams_mixed_case=True,
            test_dotnet_method_def_invalid_table=False,
            test_dotnet_max_len_exceeding_strings=False,
        )
        assert it.test_dotnet_fake_types is True
        assert it.test_dotnet_extra_data is None


class TestPEInconsistencyTestsDataclass:
    def test_creation(self):
        from redb.models.dataclasses import PEInconsistencyTests

        it = PEInconsistencyTests(
            test_rich_header_checksum=True,
            test_rich_header_duplicate=False,
            test_rich_header_linker=None,
            test_rich_header_import_count=True,
        )
        assert it.test_rich_header_checksum is True
        assert it.test_rich_header_linker is None


# ============================================================================
# YARA Dataclasses
# ============================================================================

class TestYaraRuleDataclass:
    def test_creation(self):
        from redb.models.dataclasses import YaraRule

        yr = YaraRule(
            rule_name="test_rule",
            rule_tags=["malware", "trojan"],
            rule_meta={"author": "test", "description": "A test rule"},
        )
        assert yr.rule_name == "test_rule"
        assert "malware" in yr.rule_tags


class TestYaraMatchDataclass:
    def test_creation(self):
        from redb.models.dataclasses import YaraMatch

        ym = YaraMatch(rule_name="test_rule", match_strings=["$s1", "$s2"])
        assert ym.rule_name == "test_rule"
        assert len(ym.match_strings) == 2


# ============================================================================
# ELF Dataclasses
# ============================================================================

class TestELFFeaturesDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFFeatures

        ef = ELFFeatures(
            ei_class=2, ei_data=1, ei_version=1, ei_osabi=0, ei_abiversion=0,
            e_type=2, e_machine=62, e_version=1, e_entry=0x400000, e_flags=0,
            ei_class_str="ELFCLASS64", ei_data_str="ELFDATA2LSB",
            ei_osabi_str="ELFOSABI_SYSV", e_type_str="ET_EXEC",
            e_machine_str="EM_X86_64",
            is_64bit=1, is_stripped=0, is_pie=0, has_canary=1, has_nx=1,
            has_relro=1, has_fortify=0,
            number_of_segments=9, number_of_sections=31,
            number_of_symbols=100, number_of_dynamic_symbols=50,
            number_of_relocations=25, number_of_dependencies=5,
            gnu_hash_present=1, has_debug_info=0,
        )
        assert ef.ei_class == 2
        assert ef.e_machine_str == "EM_X86_64"
        assert ef.build_id is None

    def test_with_build_id(self):
        from redb.models.dataclasses import ELFFeatures

        ef = ELFFeatures(
            ei_class=2, ei_data=1, ei_version=1, ei_osabi=0, ei_abiversion=0,
            e_type=3, e_machine=62, e_version=1, e_entry=0, e_flags=0,
            ei_class_str="64", ei_data_str="LE", ei_osabi_str="SYSV",
            e_type_str="DYN", e_machine_str="X86_64",
            is_64bit=1, is_stripped=1, is_pie=1, has_canary=0, has_nx=1,
            has_relro=1, has_fortify=0,
            number_of_segments=8, number_of_sections=28,
            number_of_symbols=0, number_of_dynamic_symbols=30,
            number_of_relocations=10, number_of_dependencies=3,
            gnu_hash_present=1, has_debug_info=0,
            build_id="abc123def456",
        )
        assert ef.build_id == "abc123def456"


class TestELFDependencyDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFDependency

        dep = ELFDependency(
            dependency_name="libc.so.6",
            dependency_type=1,
            dependency_type_str="NEEDED",
        )
        assert dep.dependency_name == "libc.so.6"


class TestELFImportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFImport

        ei = ELFImport(elf_imports_total=3)
        assert ei.elf_imports_total == 3
        assert ei.elf_import_libraries == []
        assert ei.elf_import_functions == []


class TestELFExportDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFExport

        ee = ELFExport(elf_exports_total=5)
        assert ee.elf_exports_total == 5
        assert ee.elf_export_functions == []


class TestELFSectionDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSection

        es = ELFSection(
            section_name=".text", section_type=1, section_type_str="SHT_PROGBITS",
            section_flags=6, section_flags_str=["SHF_ALLOC", "SHF_EXECINSTR"],
            section_addr=0x400000, section_offset=0x1000, section_size=4096,
            section_link=0, section_info=0, section_addralign=16, section_entsize=0,
            section_entropy=6.8, section_sha256="sha", section_md5="md5",
        )
        assert es.section_name == ".text"
        assert "SHF_ALLOC" in es.section_flags_str


class TestELFSegmentDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSegment

        seg = ELFSegment(
            segment_type=1, segment_type_str="PT_LOAD",
            segment_flags=5, segment_flags_str=["PF_R", "PF_X"],
            segment_offset=0, segment_vaddr=0x400000, segment_paddr=0x400000,
            segment_filesz=0x1000, segment_memsz=0x1000, segment_align=0x200000,
            segment_entropy=5.5, segment_sha256="sha", segment_md5="md5",
        )
        assert seg.segment_type_str == "PT_LOAD"


class TestELFSymbolDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFSymbol

        sym = ELFSymbol(
            symbol_name="main", symbol_value=0x401000, symbol_size=100,
            symbol_type=2, symbol_type_str="STT_FUNC",
            symbol_bind=1, symbol_bind_str="STB_GLOBAL",
            symbol_visibility=0, symbol_visibility_str="STV_DEFAULT",
            symbol_section_index=14, symbol_section_index_str="14",
            is_dynamic=0,
        )
        assert sym.symbol_name == "main"
        assert sym.symbol_type_str == "STT_FUNC"


class TestELFRelocationDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFRelocation

        rel = ELFRelocation(
            relocation_offset=0x601000, relocation_type=7,
            relocation_type_str="R_X86_64_JUMP_SLOT",
            relocation_symbol_index=1, relocation_symbol_name="printf",
            relocation_section=".rela.plt",
        )
        assert rel.relocation_addend is None

    def test_with_addend(self):
        from redb.models.dataclasses import ELFRelocation

        rel = ELFRelocation(
            relocation_offset=0x601000, relocation_type=7,
            relocation_type_str="R_X86_64_JUMP_SLOT",
            relocation_symbol_index=1, relocation_symbol_name="printf",
            relocation_section=".rela.plt",
            relocation_addend=-4,
        )
        assert rel.relocation_addend == -4


class TestELFNoteDataclass:
    def test_creation(self):
        from redb.models.dataclasses import ELFNote

        note = ELFNote(
            note_name="GNU", note_type=3,
            note_type_str="NT_GNU_BUILD_ID",
            note_desc="abc123", note_section=".note.gnu.build-id",
        )
        assert note.note_name == "GNU"
        assert note.note_type_str == "NT_GNU_BUILD_ID"


# ============================================================================
# Decompiled
# ============================================================================

class TestDecompiledDataclass:
    def test_creation(self):
        from redb.models.dataclasses import Decompiled

        d = Decompiled(
            _id="func_hash",
            decompiled_function_name="main",
            decompiled_function_address="0x401000",
            decompiled_function="int main() { return 0; }",
        )
        assert d.decompiled_function_name == "main"