Valentin Schwind

95 papers A* 14A 1B 14Misc 30Journal 12Unranked 23
YearRankTypeTitle / Venue / Authors
2026 conf
CHI Extended Abstracts
Stefan Resch, Yunus Söyleyici, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2026 conf
CHI Extended Abstracts
Stefan Resch, Jean-Gabriel Hanania, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2025 J jnl
ACM Trans. Comput. Hum. Interact.
Valentin Schwind, Netsanet Zelalem Tadesse, Estefania Silva da Cunha, Yeganeh Hamidi, Soltan Sanjar Sultani, Jessica Sehrt
2025 B conf
VRST
Daniel Leichinger, Valentin Schwind, Niels Henze, Martin Kocur
2025 conf
SUI
Stefan Resch, Jean-Gabriel Hanania, Daniel Schor, Esrom Johannes, Benedikt-Josip Kovac, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2025 A* conf
CHI
Martin Kocur, Melanie Kloss, Christoph Schaufler, Valentin Schwind, Niels Henze
2025 B conf
MUM
Elisa Valletta, Anna-Lena Babl, Emma Sophie Reichert, Michael Pickl, Valentin Schwind, Martin Kocur, Niels Henze
2025 conf
VR Workshops
Stefan Resch, Jean-Gabriel Hanania, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2024 conf
CHI Extended Abstracts
Jessica Sehrt, Ugur Yilmaz, Thomas Kosch, Valentin Schwind
2024 Misc conf
MuC
Jessica Sehrt, Ebony Mbamara, Mustafa Rafati, Valentin Schwind
2024 A* conf
CHI
Jessica Sehrt, Leonardo Leite Ferreira, Karsten Weyers, Amir Mahmood, Thomas Kosch, Valentin Schwind
2024 conf
MuC (Workshopband)
Martin Kocur, Valentin Schwind
2024 Misc conf
MuC
Martin Kocur, Thomas Noack, Valentin Schwind, Johanna Bogon, Niels Henze
2024 Misc conf
MuC
Stefan Resch, Rohan Brijesh Tiwari, Heer Rakeshkumar Vankawala, Priya Singh, Mustafa Rafati, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2024 conf
MobileHCI (Companion)
Stefan Resch, Lucian Zimmermann, Alexander Kunkel, Dennis Gerstung, Valentin Schwind, Diana Völz, Daniel Sánchez Morillo
2024 conf
MuC (Workshopband)
Martin Kocur, Alexander Kalus, Valentin Schwind, Niels Henze
2023 Misc conf
MuC
Stefan Resch, Mustafa Rafati, Angela Altomare, Oumaima Raddi, Arso Tahmas, Valentin Schwind, Diana Völz
2023 A* conf
CHI
Martin Kocur, Lukas Jackermeier, Valentin Schwind, Niels Henze
2023 A* conf
CHI
Jessica Sehrt, Tim Wißmann, Jan Breitenbach, Valentin Schwind
2023 J jnl
Proc. ACM Hum. Comput. Interact.
David Halbhuber, Philipp Schauhuber, Valentin Schwind, Niels Henze
2023 conf
CHI Extended Abstracts
Valentin Schwind, Stefan Resch, Jessica Sehrt
2023 Misc conf
MuC
David Halbhuber, Martin Kocur, Alexander Kalus, Kevin Angermeyer, Valentin Schwind, Niels Henze
2022 Misc conf
CHI PLAY
David Halbhuber, Julian Höpfinger, Valentin Schwind, Niels Henze
2022 J jnl
Proc. ACM Hum. Comput. Interact.
David Halbhuber, Valentin Schwind, Niels Henze
2022 Misc conf
MuC
Alexander Kalus, Martin Kocur, Niels Henze, Johanna Bogon, Valentin Schwind
2022 B conf
CHIIR
Maximiliane Windl, Anna-Marie Ortloff, Niels Henze, Valentin Schwind
2022 J jnl
Big Data Cogn. Comput.
Jessica Sehrt, Bent Braams, Niels Henze, Valentin Schwind
2022 B conf
VRST
Martin Kocur, Johanna Bogon, Manuel Mayer, Miriam Witte, Amelie Karber, Niels Henze, Valentin Schwind
2022 Misc conf
MuC
Jessica Sehrt, Henrico Putra Neumann, Julian Niclas Wenzel, Luca Kindermann, Valentin Schwind
2022 B conf
VRST
Martin Kocur, Alexander Kalus, Johanna Bogon, Niels Henze, Christian Wolff, Valentin Schwind
2022 Misc conf
CHI PLAY
David Halbhuber, Maximilian Huber, Valentin Schwind, Niels Henze
2022 Misc conf
MuC
Jessica Sehrt, Feng Yi Lu, Leonard Husske, Anton Roesler, Valentin Schwind
2021 conf
CHI Extended Abstracts
Dmitry Alexandrovsky, Susanne Putze, Valentin Schwind, Elisa D. Mekler, Jan David Smeddinck, Denise Kahl, Antonio Krüger, Rainer Malaka
2021 J jnl
CoRR
Dmitry Alexandrovsky, Susanne Putze, Valentin Schwind, Elisa D. Mekler, Jan David Smeddinck, Denise Kahl, Antonio Krüger, Rainer Malaka
2021 J jnl
Proc. ACM Hum. Comput. Interact.
David Halbhuber, Niels Henze, Valentin Schwind
2021 A* conf
CHI
Martin Kocur, Florian Habler, Valentin Schwind, Pawel W. Wozniak, Christian Wolff, Niels Henze
2021 A* conf
CHI
Rufat Rzayev, Polina Ugnivenko, Sarah Graf, Valentin Schwind, Niels Henze
2021 conf
MuC (Workshopband)
Martin Kocur, Niels Henze, Valentin Schwind
2020 Misc conf
NordiCHI
Valentin Schwind, Niels Henze
2020 J jnl
Interactions
Francisco Kiss, Sven Mayer, Valentin Schwind
2020 Misc conf
NordiCHI
Rufat Rzayev, Susanne Korbely, Milena Maul, Alina Schark, Valentin Schwind, Niels Henze
2020 Misc conf
MuC
Rufat Rzayev, Sabrina Hartl, Vera Wittmann, Valentin Schwind, Niels Henze
2020 Misc conf
CHI PLAY
Martin Kocur, Melanie Kloss, Valentin Schwind, Christian Wolff, Niels Henze
2020 A conf
Conference on Designing Interactive Systems
Anna-Marie Ortloff, Maximiliane Windl, Valentin Schwind, Niels Henze
2020 A* conf
CHI
Sven Mayer, Jens Reinhardt, Robin Schweigert, Brighten Jelke, Valentin Schwind, Katrin Wolf, Niels Henze
2020 B conf
VRST
Sarah Graf, Valentin Schwind
2020 conf
CHI Extended Abstracts
Rufat Rzayev, Florian Habler, Polina Ugnivenko, Niels Henze, Valentin Schwind
2020 J jnl
IEEE Pervasive Comput.
Niels Henze, Valentin Schwind, Katrin Wolf, Martin Kocur, Albrecht Schmidt, Andrew L. Kun
2020 B conf
VRST
Valentin Schwind, David Halbhuber, Jakob Fehle, Jonathan Sasse, Andreas Pfaffelhuber, Christoph Tögel, Julian Dietz, Niels Henze
2020 B conf
VRST
Martin Kocur, Philipp Schauhuber, Valentin Schwind, Christian Wolff, Niels Henze
2020 B conf
VRST
Martin Kocur, Sarah Graf, Valentin Schwind
2020 conf
MuC (Workshopband)
Martin Kocur, Daniel Roth, Valentin Schwind
2019 conf
INTERACT (4)
Marion Koelle, Ceenu George, Valentin Schwind, Daniel Perry, Yumiko Sakamoto, Khalad Hasan, Robb Mitchell, Thomas Olsson
2019 A* conf
CHI
Sven Mayer, Valentin Schwind, Huy Viet Le, Dominik Weber, Jonas Vogelsang, Johannes Wolf, Niels Henze
2019 Misc conf
MuC
Florian Habler, Valentin Schwind, Niels Henze
2019 Misc conf
MuC
Robin Schweigert, Valentin Schwind, Sven Mayer
2019 B conf
MobileHCI
Rufat Rzayev, Gürkan Karaman, Niels Henze, Valentin Schwind
2019 A* conf
CHI
Alexandra Voit, Sven Mayer, Valentin Schwind, Niels Henze
2019 Misc conf
MuC
Sven Mayer, Lars Lischke, Valentin Schwind, Markus Gärtner, Eric Hämmerle, Emine Turcan, Florin Rheinwald, Gustav Murawski, Jonas Kuhn, Niels Henze
2019 Misc conf
MuC
Rufat Rzayev, Gürkan Karaman, Katrin Wolf, Niels Henze, Valentin Schwind
2019 Misc conf
MuC
Valentin Schwind, Jan Leusmann, Niels Henze
2019 B conf
MUM
Lars Lischke, Valentin Schwind, Robin Schweigert, Pawel W. Wozniak, Niels Henze
2019 A* conf
CHI
Valentin Schwind, Niklas Deierlein, Romina Poguntke, Niels Henze
2019 A* conf
CHI
Valentin Schwind, Pascal Knierim, Nico Haas, Niels Henze
2019 conf
MuC (Workshopband)
Martin Kocur, Valentin Schwind, Niels Henze
2018 J jnl
Interactions
Valentin Schwind, Katrin Wolf, Niels Henze
2018 Misc conf
CHI PLAY
Valentin Schwind, Niels Henze
2018 conf
CHI Extended Abstracts
Elhassan Makled, Yomna Abdelrahman, Noha Mokhtar, Valentin Schwind, Slim Abdennadher, Albrecht Schmidt
2018
Valentin Schwind
2018 J jnl
Int. J. Hum. Comput. Stud.
Valentin Schwind, Katharina Leicht, Solveigh Jäger, Katrin Wolf, Niels Henze
2018 conf
COLING (Demos)
Markus Gärtner, Sven Mayer, Valentin Schwind, Eric Hämmerle, Emine Turcan, Florin Rheinwald, Gustav Murawski, Lars Lischke, Jonas Kuhn
2018 A* conf
CHI
Pascal Knierim, Valentin Schwind, Anna Maria Feit, Florian Nieuwenhuizen, Niels Henze
2018 A* conf
CHI
Sven Mayer, Valentin Schwind, Robin Schweigert, Niels Henze
2018 B conf
SAP
Valentin Schwind, Lorraine Lin, Massimiliano Di Luca, Sophie Jörg, James Hillis
2018 Misc conf
CHI PLAY
Valentin Schwind, Sven Mayer, Alexandre Comeau-Vermeersch, Robin Schweigert, Niels Henze
2018 conf
MobileHCI Adjunct
Valentin Schwind, Jens Reinhardt, Rufat Rzayev, Niels Henze, Katrin Wolf
2017 A* conf
CHI
Valentin Schwind, Pascal Knierim, Cagri Tasci, Patrick Franczak, Nico Haas, Niels Henze
2017 Misc conf
CHI PLAY
Valentin Schwind, Pascal Knierim, Lewis L. Chuang, Niels Henze
2017 B conf
MUM
Francisco Kiss, Valentin Schwind, Stefan Schneegass, Niels Henze
2017 B conf
MobileHCI
Niels Henze, Sven Mayer, Huy Viet Le, Valentin Schwind
2017 Misc conf
ISS
Huy Viet Le, Valentin Schwind, Philipp Göttlich, Niels Henze
2017 J jnl
Comput. Entertain.
Oliver Korn, Michael Blatz, Adrian Rees, Jakob Schaal, Valentin Schwind, Daniel Görlich
2017 conf
CHI Extended Abstracts
Pascal Knierim, Thomas Kosch, Valentin Schwind, Markus Funk, Francisco Kiss, Stefan Schneegass, Niels Henze
2016 conf
MobileHCI Adjunct
Alexandra Voit, Tonja Machulla, Dominik Weber, Valentin Schwind, Stefan Schneegass, Niels Henze
2016 conf
CHI Extended Abstracts
Lars Lischke, Valentin Schwind, Kai Friedrich, Albrecht Schmidt, Niels Henze
2016 Misc conf
ISWC
Tilman Dingler, Rufat Rzayev, Valentin Schwind, Niels Henze
2016 J jnl
i-com
Valentin Schwind, Solveigh Jäger
2015 Misc conf
MuC
Valentin Schwind, Norman Pohl, Patrick Bader
2015 Misc conf
CHI PLAY
Valentin Schwind, Katrin Wolf, Niels Henze, Oliver Korn
2015 Misc conf
MuC
Patrick Bader, Norman Pohl, Valentin Schwind, Niels Henze, Katrin Wolf, Stefan Schneegass, Albrecht Schmidt
2015 conf
INTERACT (4)
Patrick Bader, Valentin Schwind, Norman Pohl, Niels Henze, Katrin Wolf, Stefan Schneegass, Albrecht Schmidt
2015 conf
CHI Extended Abstracts
Katrin Wolf, Stefan Schneegass, Niels Henze, Dominik Weber, Valentin Schwind, Pascal Knierim, Sven Mayer, Tilman Dingler, Yomna Abdelrahman, Thomas Kubitza, Markus Funk, Anja Mebus, Albrecht Schmidt
2015 Misc conf
MuC
Valentin Schwind, Solveigh Jäger
2014 Misc conf
NordiCHI
Patrick Bader, Stefan Schneegass, Niels Henze, Valentin Schwind, Katrin Wolf
2014 Misc conf
NordiCHI
Patrick Bader, Valentin Schwind, Niels Henze, Stefan Schneegass, Nora Broy, Albrecht Schmidt
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"