Rafael A. Calvo

176 papers A* 1A 10B 19C 4Misc 17Journal 70Unranked 55
YearRankTypeTitle / Venue / Authors
2026 conf
CHI Extended Abstracts
Yao Xiao, Rafael A. Calvo
2026 J jnl
CoRR
Yao Xiao, Rafael A. Calvo
2026 conf
CHI Extended Abstracts
Dorian Peters, Tomasz Hollanek, Naseem Ahmadpour, Rafael A. Calvo, Sai Shruthi Chivukula, Christian Dindler, Colin M. Gray, Shaimaa Lazem, Gizem Öz, Nadia Piet
2026 conf
CHI Extended Abstracts
Hansoo Lee, Yoonjae Cho, Sonya S. Kwak, Rafael A. Calvo
2026 J jnl
Interact. Comput.
Nick Ballou, Dorian Peters, Gabriela Villalobos-Zúñiga, Elisa D. Mekler, Rafael A. Calvo, Sebastian Deterding
2026 A* conf
CHI
Zheyuan Zhang, Dorian Peters, Lan Xiao, Jingjing Sun, Laura Moradbakhti, Andrew Hall, Rafael A. Calvo
2026 J jnl
CoRR
Zheyuan Zhang, Dorian Peters, Lan Xiao, Jingjing Sun, Laura Moradbakhti, Andrew Hall, Rafael A. Calvo
2025 J jnl
CoRR
Laura Moradbakhti, Dorian Peters, Jennifer K. Quint, Björn W. Schuller, Darren Cook, Rafael A. Calvo
2025 A conf
Conference on Designing Interactive Systems
Zheyuan Zhang, Jingjing Sun, Dorian Peters, Rafael A. Calvo
2025 J jnl
CoRR
Zheyuan Zhang, Jingjing Sun, Dorian Peters, Rafael A. Calvo
2025 J jnl
AI Soc.
Malak Sadek, Emma Kallina, Thomas Bohné, Céline Mougenot, Rafael A. Calvo, Stephen Cave
2025 J jnl
CoRR
Rafael A. Calvo, Dorian Peters
2025 conf
CHI Extended Abstracts
Marco Da Re, Fernanda Espinoza, Maria Veronica Belón-Hercilla, Cecilia Anza-Ramirez, Nilton Santos Custodio Capuñay, Rosa Montesinos Zevallos, Maria Sofia Cuba-Fuentes, Christopher R. Butler, Rafael A. Calvo
2025 J jnl
CoRR
Guido Ivetta, Laura Moradbakhti, Rafael A. Calvo
2025 J jnl
Int. J. Hum. Comput. Interact.
Malak Sadek, Rafael A. Calvo, Céline Mougenot
2025 J jnl
CoRR
Dorian Peters, Fernanda Espinoza, Marco Da Re, Guido Ivetta, Luciana Benotti, Rafael A. Calvo
2024 J jnl
IEEE Technol. Soc. Mag.
Malak Sadek, Rafael A. Calvo, Céline Mougenot
2024 J jnl
AI Ethics
Malak Sadek, Rafael A. Calvo, Céline Mougenot
2024 J jnl
Interactions
Fernanda Espinoza, Marco Da Re, Rafael A. Calvo
2023 C conf
ICMLA
Alina-Irina Serban, Helen Lai, Sarah Daniels, Rafael A. Calvo, David J. Sharp, Eyal Soreq
2023 Misc conf
ICASSP
Georgios Rizos, Rafael A. Calvo, Björn W. Schuller
2023 J jnl
Int. J. Hum. Comput. Interact.
Muhammad Johan Alibasa, Rafael A. Calvo, Kalina Yacef
2023 J jnl
CoRR
Malak Sadek, Rafael A. Calvo, Céline Mougenot
2023 conf
CUI
Malak Sadek, Rafael A. Calvo, Céline Mougenot
2022 J jnl
Int. J. Medical Informatics
Rebecca M. Jedwab, Alison M. Hutchinson, Elizabeth Manias, Rafael A. Calvo, Naomi Dobroff, Bernice Redley
2022 J jnl
Multimodal Technol. Interact.
Kiran Ijaz, Tram Thi Minh Tran, Ahmet Baki Kocaballi, Rafael A. Calvo, Shlomo Berkovsky, Naseem Ahmadpour
2022 J jnl
IEEE Trans. Affect. Comput.
Muhammad Johan Alibasa, Rizka Widyarini Purwanto, Kalina Yacef, Nick Glozier, Rafael A. Calvo
2022 conf
IUI Companion
Katrin Hänsel, Michael Sobolev, Tobias Kowatsch, Rafael A. Calvo
2022 conf
CHI Extended Abstracts
Nick Ballou, Sebastian Deterding, April Tyack, Elisa D. Mekler, Rafael A. Calvo, Dorian Peters, Gabriela Villalobos-Zúñiga, Selen Turkay
2022 J jnl
npj Digit. Medicine
Alina-Irina Serban, Eyal Soreq, Payam M. Barnaghi, Sarah Daniels, Rafael A. Calvo, David J. Sharp
2022 conf
UbiComp/ISWC Adjunct
Cassandra E. L. Seah, Sijin Sun, Zheyuan Zhang, Talya Porat, Andrew Waterhouse, Rafael A. Calvo
2021 conf
ICMI Companion
Joshua Y. Kim, Rafael A. Calvo, N. J. Enfield, Kalina Yacef
2021 conf
CHI Extended Abstracts
Ajit G. Pillai, Ahmet Baki Kocaballi, Tuck Wah Leong, Rafael A. Calvo, Nassim Parvin, Katie Shilton, Jenny Waycott, Casey Fiesler, John C. Havens, Naseem Ahmadpour
2021 conf
IWSDS
Joshua Y. Kim, Chunfeng Liu, Rafael A. Calvo, Kathryn McCabe, Silas C. R. Taylor, Björn W. Schuller, Kaihang Wu
2021 conf
CHI Extended Abstracts
Dorian Peters, Rafael A. Calvo
2021 conf
Nursing Informatics
Somtochukwu Amaka Osajiuba, Rebecca M. Jedwab, Rafael A. Calvo, Naomi Dobroff, Nicholas Glozier, Alison M. Hutchinson, Michael Leiter, Katrina Nankervis, Helen Rawson, Bernice Redley, Elizabeth Manias
2021 A conf
EACL
Joshua Y. Kim, Kalina Yacef, Greyson Y. Kim, Chunfeng Liu, Rafael A. Calvo, Silas Taylor
2021 J jnl
CoRR
Joshua Y. Kim, Greyson Y. Kim, Chunfeng Liu, Rafael A. Calvo, Silas C. R. Taylor, Kalina Yacef
2021 conf
Nursing Informatics
Shaluni Tissera, Rebecca M. Jedwab, Rafael A. Calvo, Naomi Dobroff, Nicholas Glozier, Alison M. Hutchinson, Michael Leiter, Elizabeth Manias, Katrina Nankervis, Helen Rawson, Bernice Redley
2020 J jnl
Int. J. Hum. Comput. Interact.
Khushnood Z. Naqshbandi, Chunfeng Liu, Silas Taylor, Renee Lim, Naseem Ahmadpour, Rafael A. Calvo
2020 J jnl
Nat. Mach. Intell.
Rafael A. Calvo, Dorian Peters, Stephen Cave
2020 J jnl
Int. J. Hum. Comput. Interact.
Kaihang Wu, Chunfeng Liu, Rafael A. Calvo
2020 J jnl
IEEE Trans. Affect. Comput.
Leandro A. Bugnon, Rafael A. Calvo, Diego H. Milone
2020 J jnl
Int. J. Hum. Comput. Interact.
Kiran Ijaz, Naseem Ahmadpour, Yifan Wang, Rafael A. Calvo
2020 J jnl
Multimodal Technol. Interact.
Dorian Peters, Naseem Ahmadpour, Rafael A. Calvo
2020 J jnl
Softw. Pract. Exp.
Yifan Wang, Kiran Ijaz, Dong Yuan, Rafael A. Calvo
2019 conf
CHI Extended Abstracts
John B. Torous, Maria K. Wolters, Greg Wadley, Rafael A. Calvo
2019 J jnl
CoRR
Joshua Y. Kim, Chunfeng Liu, Rafael A. Calvo, Kathryn McCabe, Silas C. R. Taylor, Björn W. Schuller, Kaihang Wu
2019 J jnl
CoRR
Joshua Y. Kim, Rafael A. Calvo, Kalina Yacef, N. J. Enfield
2019 conf
CHI Extended Abstracts
Rafael A. Calvo, Dorian Peters
2019 conf
CHI Extended Abstracts
Kiran Ijaz, Yifan Wang, Naseem Ahmadpour, Rafael A. Calvo
2019 J jnl
IEEE Access
Muhammad Johan Alibasa, Rafael A. Calvo, Kalina Yacef
2019 J jnl
Comput. Hum. Behav.
Chunfeng Liu, Renee Lim, Silas Taylor, Rafael A. Calvo
2019 B conf
ACII
Muhammad Johan Alibasa, Rafael A. Calvo
2018 Misc conf
OZCHI
Dorian Peters, Susan Hansen, Jenny McMullan, Theresa Ardler, Janet Mooney, Rafael A. Calvo
2018 conf
CHI Extended Abstracts
Greg Wadley, Rafael A. Calvo, John B. Torous, Mary Czerwinski
2018 Misc conf
OZCHI
Rafael A. Calvo, Dorian Peters, Julian Huppert, Gerard Goggin
2018 conf
CLPsych@NAACL-HTL
Edgar Altszyler, Ariel J. Berenstein, David N. Milne, Rafael A. Calvo, Diego Fernández Slezak
2018 J jnl
Interactions
Dorian Peters, Rafael A. Calvo
2017 J jnl
IEEE Trans. Affect. Comput.
Hamed Monkaresi, Nigel Bosch, Rafael A. Calvo, Sidney K. D'Mello
2017 J jnl
ACM Trans. Interact. Intell. Syst.
Nargess Nourbakhsh, Fang Chen, Yang Wang, Rafael A. Calvo
2017 J jnl
Nat. Lang. Eng.
Rafael A. Calvo, David N. Milne, M. Sazzad Hussain, Helen Christensen
2017 Misc conf
OZCHI
Kiran Ijaz, Naseem Ahmadpour, Rafael A. Calvo
2017 conf
CHI Extended Abstracts
Rafael A. Calvo, Dorian Peters
2016 conf
CLPsych@HLT-NAACL
David N. Milne, Glen Pink, Ben Hachey, Rafael A. Calvo
2016 conf
JCSG
Kiran Ijaz, Yifan Wang, David N. Milne, Rafael A. Calvo
2016 conf
CHI Extended Abstracts
Rafael A. Calvo, Karthik Dinakar, Rosalind W. Picard, Pattie Maes
2016 conf
CHI Extended Abstracts
Rafael A. Calvo, Dorian Peters
2016 C conf
HIS
Chunfeng Liu, Rafael A. Calvo, Renee Lim, Silas Taylor
2016 Misc conf
OZCHI
Khushnood Z. Naqshbandi, David N. Milne, Ben Davies, Sophie Potter, Rafael A. Calvo, Simon Hoermann
2016 J jnl
Frontiers ICT
Chunfeng Liu, Rafael A. Calvo, Renee Lim
2016 conf
AAAI Spring Symposia
Rafael A. Calvo, Nick Haber, Catalin Voss, Michael Nova, Dennis Salins, Michael Snyder, Dennis P. Wall
2016 J jnl
IEEE Trans. Emerg. Top. Comput.
Danan Thilakanathan, Shiping Chen, Surya Nepal, Rafael A. Calvo
2016 conf
JCSG
Kiran Ijaz, Yifan Wang, David N. Milne, Rafael A. Calvo
2015 J jnl
Comput. Hum. Behav.
Jason M. Harley, François Bouchet, M. Sazzad Hussain, Roger Azevedo, Rafael A. Calvo
2015 J jnl
Evol. Syst.
Omar AlZoubi, Davide Fossati, Sidney K. D'Mello, Rafael A. Calvo
2015 A conf
LAK
Abelardo Pardo, Robert A. Ellis, Rafael A. Calvo
2015 conf
BODYNETS
Hamed Monkaresi, Rafael A. Calvo
2015 conf
CHI Extended Abstracts
Rafael A. Calvo, Dorian Peters
2015 J jnl
IEEE Trans. Learn. Technol.
Ming Liu, Rafael A. Calvo, Abelardo Pardo, Andrew Martin
2015 conf
CHI Extended Abstracts
Mohammed Sazzad Hussain, Rafael A. Calvo, Louise A. Ellis, Juchen Li, Laura Ospina-Pinillos, Tracey Davenport, Ian B. Hickie
2015 B conf
CCGRID
Shiping Chen, Danan Thilakanathan, Donna Xu, Surya Nepal, Rafael A. Calvo
2015 Misc conf
OZCHI
Kjartan Nordbo, David N. Milne, Rafael A. Calvo, Margaret Allman-Farinelli
2015 Misc conf
OZCHI
Yu Zhao, Rafael A. Calvo, Abelardo Pardo, Harriet Gunn, Kate Steinbeck
2015 J jnl
Commun. ACM
Rafael A. Calvo, Dorian Peters, Sidney K. D'Mello
2014 J jnl
IEEE J. Biomed. Health Informatics
Hamed Monkaresi, Rafael A. Calvo, Hong Yan
2014 J jnl
Future Gener. Comput. Syst.
Danan Thilakanathan, Shiping Chen, Surya Nepal, Rafael A. Calvo, Leila Alem
2014 J jnl
IEEE Trans. Affect. Comput.
Rafael A. Calvo, Giuseppe Riva, Christine L. Lisetti
2014 J jnl
Interact. Comput.
M. Sazzad Hussain, Rafael A. Calvo, Fang Chen
2014 J jnl
J. Educ. Technol. Soc.
Ming Liu, Rafael A. Calvo, Vasile Rus
2014 conf
CHI Extended Abstracts
Rafael A. Calvo, Dorian Peters, Daniel M. Johnson, Yvonne Rogers
2014 J jnl
Interactions
Dorian Peters, Rafael A. Calvo
2014 J jnl
Int. J. Parallel Emergent Distributed Syst.
Ifeanyi P. Egwutuoha, Shiping Chen, David Levy, Bran Selic, Rafael A. Calvo
2014 J jnl
J. Complex Networks
Yuriy Hulovatyy, Sidney K. D'Mello, Rafael A. Calvo, Tijana Milenkovic
2014 conf
CBD
Danan Thilakanathan, Yu Zhao, Shiping Chen, Surya Nepal, Rafael A. Calvo, Abelardo Pardo
2014 conf
IEEE CLOUD
Danan Thilakanathan, Shiping Chen, Surya Nepal, Rafael A. Calvo, Dongxi Liu, John Zic
2014 Misc conf
FLAIRS
Hamed Monkaresi, M. Sazzad Hussain, Rafael A. Calvo
2013 J jnl
J. Univers. Comput. Sci.
Jorge J. Villalón, Rafael A. Calvo
2013 conf
ICMLA (1)
Omar AlZoubi, Davide Fossati, Sidney K. D'Mello, Rafael A. Calvo
2013 A conf
LAK
Vilaythong Southavilay, Kalina Yacef, Peter Reimann, Rafael A. Calvo
2013 conf
CHI Extended Abstracts
Sidney K. D'Mello, Rafael A. Calvo
2013 J jnl
Comput. Intell.
Rafael A. Calvo, Sunghwan Mac Kim
2013 conf
SITIS
Yuriy Hulovatyy, Sidney K. D'Mello, Rafael A. Calvo, Tijana Milenkovic
2013 B ed.
EDM
Sidney K. D'Mello, Rafael A. Calvo, Andrew Olney
2013 J jnl
IEEE Technol. Soc. Mag.
Rafael A. Calvo, Dorian Peters
2013 conf
CSE
Danan Thilakanathan, Rafael A. Calvo, Shiping Chen, Surya Nepal
2013 Misc conf
OZCHI
Rafael A. Calvo, Dorian Peters
2013 B conf
ICALT
Ming Liu, Rafael A. Calvo, Abelardo Pardo
2012 conf
Australasian Conference on Artificial Intelligence
Hamed Monkaresi, M. Sazzad Hussain, Rafael A. Calvo
2012 A conf
ICWS
Zheng Yang, Jinhui Yao, Shiping Chen, David Levy, Rafael A. Calvo
2012 conf
CGC
Ifeanyi P. Egwutuoha, Shiping Chen, David Levy, Bran Selic, Rafael A. Calvo
2012 B conf
AVI
Hamed Monkaresi, Rafael A. Calvo, M. Sazzad Hussain
2012 B conf
ITS
M. Sazzad Hussain, Hamed Monkaresi, Rafael A. Calvo
2012 B conf
SMC
Hamed Monkaresi, M. Sazzad Hussain, Rafael A. Calvo
2012 Misc conf
AusDM
M. Sazzad Hussain, Hamed Monkaresi, Rafael A. Calvo
2012 J jnl
IEEE Trans. Affect. Comput.
Omar AlZoubi, Sidney K. D'Mello, Rafael A. Calvo
2012 J jnl
IEEE Intell. Syst.
Rafael A. Calvo, Sidney K. D'Mello
2012 J jnl
Dialogue Discourse
Ming Liu, Rafael A. Calvo, Vasile Rus
2012 C conf
ICCE
Ming Liu, Rafael A. Calvo, Vasile Rus
2012 J jnl
Interactions
Rafael A. Calvo, Dorian Peters
2012 Misc conf
FLAIRS
Rafael A. Calvo
2012 conf
ICLS
Rafael A. Calvo, Anindito Aditomo, Vilaythong Southavilay, Kalina Yacef
2012 B conf
ITS
Ming Liu, Rafael A. Calvo
2012 J jnl
IEEE Trans. Learn. Technol.
Ming Liu, Rafael A. Calvo, Anindito Aditomo, Luiz Augusto Pizzato
2012 Misc conf
OZCHI
Nargess Nourbakhsh, Yang Wang, Fang Chen, Rafael A. Calvo
2011 A conf
AIED
M. Sazzad Hussain, Omar AlZoubi, Rafael A. Calvo, Sidney K. D'Mello
2011 conf
ACII (1)
Omar AlZoubi, M. Sazzad Hussain, Sidney K. D'Mello, Rafael A. Calvo
2011 J jnl
IEEE Trans. Learn. Technol.
Rafael A. Calvo, Stephen T. O'Rourke, Janet Jones, Kalina Yacef, Peter Reimann
2011 conf
CSCL
Anindito Aditomo, Rafael A. Calvo, Peter Reimann
2011 J jnl
J. Educ. Technol. Soc.
Jorge J. Villalón, Rafael A. Calvo
2011 conf
ACII (1)
M. Sazzad Hussain, Rafael A. Calvo, Payam Aghaei Pour
2011 A conf
AIED
M. Sazzad Hussain, Rafael A. Calvo
2011 A conf
AIED
Ming Liu, Rafael A. Calvo
2011 A conf
AIED
Sunghwan Mac Kim, Rafael A. Calvo
2011 conf
ACII (2)
Rafael A. Calvo, M. Sazzad Hussain, Payam Aghaei Pour, Omar AlZoubi
2011 Misc conf
FLAIRS
Sidney K. D'Mello, Rafael A. Calvo
2011 conf
ACII (1)
Payam Aghaei Pour, Rafael A. Calvo
2011 J jnl
J. Educ. Technol. Soc.
Stephen T. O'Rourke, Rafael A. Calvo, Danielle S. McNamara
2010 J jnl
IEEE Trans. Affect. Comput.
Rafael A. Calvo, Sidney K. D'Mello
2010 conf
ICDM Workshops
Vilaythong Southavilay, Kalina Yacef, Rafael A. Calvo
2010 B conf
Intelligent Tutoring Systems (1)
Ming Liu, Rafael A. Calvo, Vasile Rus
2010 C conf
ICCE
Peter Reimann, Rafael A. Calvo, Kalina Yacef, Vilaythong Southavilay
2010 B conf
EDM
Vilaythong Southavilay, Kalina Yacef, Rafael A. Calvo
2010 B conf
EDM
Sunghwan Mac Kim, Rafael A. Calvo
2010 B conf
Intelligent Tutoring Systems (1)
Payam Aghaei Pour, M. Sazzad Hussain, Omar AlZoubi, Sidney K. D'Mello, Rafael A. Calvo
2009 conf
ICE-GIC
Jae-Moon Lee, Se Hong Cho, Rafael A. Calvo
2009 A conf
AIED
Stephen T. O'Rourke, Rafael A. Calvo
2009 conf
Australasian Conference on Artificial Intelligence
Omar AlZoubi, Rafael A. Calvo, Ronald H. Stevens
2009 B conf
ICALT
Jorge J. Villalón, Rafael A. Calvo
2009 conf
Australasian Conference on Artificial Intelligence
Rafael A. Calvo, Iain Brown, Steve Scheding
2009 B conf
ICALT
Rafael A. Calvo
2009 Misc conf
AusDM
Jorge J. Villalón, Rafael A. Calvo
2009 B conf
ICALT
Stephen T. O'Rourke, Rafael A. Calvo
2008 B conf
ICALT
Ungkyu Park, Rafael A. Calvo
2008 conf
CIG
Payam Aghaei Pour, Tauseef Gulrez, Omar AlZoubi, Gaetano D. Gargiulo, Rafael A. Calvo
2008 Misc conf
AusDM
Omar AlZoubi, Irena Koprinska, Rafael A. Calvo
2008 conf
Web Intelligence/IAT Workshops
Jorge J. Villalón, Rafael A. Calvo
2008 B conf
ICALT
Jorge J. Villalón, Paul Kearney, Rafael A. Calvo, Peter Reimann
2007 J jnl
IEEE Trans. Educ.
Nicholas L. Carroll, Lina Markauskaite, Rafael A. Calvo
2007 J jnl
J. Educ. Technol. Soc.
Robert A. Ellis, Rafael A. Calvo
2006 conf
Mobility Conference
Jingyu Zhang, Rafael A. Calvo, Richard William Shephard, Craig T. Jin
2006 J jnl
Br. J. Educ. Technol.
Robert A. Ellis, Rafael A. Calvo
2006 J jnl
IEEE Internet Comput.
Juan Jose García Adeva, Rafael A. Calvo
2005 conf
ICITA (1)
Juan Jose García Adeva, Rafael A. Calvo
2005 J jnl
CLEI Electron. J.
Juan Jose García Adeva, Ulises Cerviño Beresi, Rafael A. Calvo
2005 B conf
ICWE
Aiman Turani, Rafael A. Calvo, Peter Goodyear
2005 conf
ICITA (2)
Nicholas L. Carroll, Rafael A. Calvo
2005 B conf
ICWE
Nicholas L. Carroll, Rafael A. Calvo
2005 J jnl
Intell. Data Anal.
Jae-Moon Lee, Rafael A. Calvo
2004 conf
Australian Conference on Artificial Intelligence
Robert Dale, Rafael A. Calvo, Marc Tilbrook
2004 J jnl
J. Digit. Inf.
Rafael A. Calvo, Jae-Moon Lee, Xiaobo Li
2002 Misc conf
ADCS
Ken Williams, Rafael A. Calvo
2002 Misc conf
ADCS
Rafael A. Calvo, Ken Williams
2000 J jnl
Intell. Data Anal.
Rafael A. Calvo, H. Alejandro Ceccatto
1998 conf
SBRN
Rafael A. Calvo
1998 J jnl
Intell. Data Anal.
Matthew Partridge, Rafael A. Calvo
tests/unit/test_apk_dataclasses.py
← Index tests/unit/test_apk_dataclasses.py python
"""
Unit tests for APK dataclasses in redb/models/dataclasses.py.
"""
import pytest
from dataclasses import asdict, fields

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


# ============================================================================
# APKFeatures
# ============================================================================

class TestAPKFeaturesDataclass:
    """Tests for APKFeatures dataclass."""

    def test_named_fields(self):
        from redb.models.dataclasses import APKFeatures

        f = APKFeatures(
            package_name="com.example.app",
            app_name="Example App",
            version_code=1,
            version_name="1.0.0",
        )
        assert f.package_name == "com.example.app"
        assert f.app_name == "Example App"
        assert f.version_code == 1
        assert f.version_name == "1.0.0"

    def test_all_fields_default_none_or_safe(self):
        from redb.models.dataclasses import APKFeatures

        f = APKFeatures()
        # Nullable fields default to None
        assert f.package_name is None
        assert f.app_name is None
        assert f.version_code is None
        assert f.version_name is None
        assert f.min_sdk_version is None
        assert f.target_sdk_version is None
        assert f.compile_sdk_version is None
        assert f.main_activity is None
        # Non-nullable fields have safe defaults
        assert f.is_debuggable is False
        assert f.allow_backup is True
        assert f.uses_cleartext_traffic is False
        assert f.supported_abis == []
        assert f.dex_count == 0
        assert f.total_dex_size == 0
        assert f.total_file_count == 0
        assert f.has_native_code is False
        assert f.has_assets is False
        assert f.uses_libraries == []
        assert f.earliest_content_modification is None
        assert f.latest_content_modification is None
        assert f.contains_embedded_apk is False

    def test_all_fields_populated(self):
        from redb.models.dataclasses import APKFeatures

        f = APKFeatures(
            package_name="com.malware.test",
            app_name="Malware",
            version_code=42,
            version_name="6.6.6",
            min_sdk_version=21,
            target_sdk_version=33,
            compile_sdk_version=33,
            main_activity="com.malware.test.MainActivity",
            is_debuggable=True,
            allow_backup=False,
            uses_cleartext_traffic=True,
            supported_abis=["armeabi-v7a", "arm64-v8a", "x86"],
            dex_count=3,
            total_dex_size=5000000,
            total_file_count=200,
            has_native_code=True,
            has_assets=True,
            uses_libraries=["com.google.android.maps"],
            earliest_content_modification="2024-01-01T00:00:00Z",
            latest_content_modification="2024-06-15T12:00:00Z",
            contains_embedded_apk=True,
        )
        assert f.is_debuggable is True
        assert f.dex_count == 3
        assert len(f.supported_abis) == 3
        assert f.contains_embedded_apk is True

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

        f = APKFeatures(
            package_name="com.test",
            app_name="Test",
            version_code=1,
            version_name="1.0",
        )
        d = asdict(f)
        assert d["package_name"] == "com.test"
        assert d["is_debuggable"] is False
        assert d["supported_abis"] == []

    def test_partial_extraction(self):
        """Verify that APKFeatures can be created with only some fields populated,
        simulating a partial extraction where some fields failed."""
        from redb.models.dataclasses import APKFeatures

        f = APKFeatures(
            package_name="com.example.app",
            # app_name failed to extract — left as None
            version_code=10,
            # version_name failed to extract — left as None
            is_debuggable=True,
            dex_count=2,
        )
        assert f.package_name == "com.example.app"
        assert f.app_name is None
        assert f.version_code == 10
        assert f.version_name is None
        assert f.is_debuggable is True
        assert f.dex_count == 2


# ============================================================================
# APKManifestComponent
# ============================================================================

class TestAPKManifestComponentDataclass:

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

        c = APKManifestComponent(
            component_type="activity",
            class_name="com.example.MainActivity",
            is_exported=True,
            intent_actions=["android.intent.action.MAIN"],
            intent_categories=["android.intent.category.LAUNCHER"],
        )
        assert c.component_type == "activity"
        assert c.class_name == "com.example.MainActivity"
        assert c.is_exported is True
        assert len(c.intent_actions) == 1
        assert len(c.intent_categories) == 1

    def test_defaults(self):
        from redb.models.dataclasses import APKManifestComponent

        c = APKManifestComponent(
            component_type="service",
            class_name="com.example.MyService",
            is_exported=False,
        )
        assert c.intent_actions == []
        assert c.intent_categories == []


# ============================================================================
# APKManifest
# ============================================================================

class TestAPKManifestDataclass:

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

        m = APKManifest(
            activity_count=5,
            service_count=2,
            receiver_count=3,
            provider_count=1,
        )
        assert m.activity_count == 5
        assert m.service_count == 2
        assert m.receiver_count == 3
        assert m.provider_count == 1

    def test_optional_list_defaults(self):
        from redb.models.dataclasses import APKManifest

        m = APKManifest(
            activity_count=0,
            service_count=0,
            receiver_count=0,
            provider_count=0,
        )
        assert m.activities == []
        assert m.services == []
        assert m.receivers == []
        assert m.providers == []
        assert m.exported_components == []
        assert m.intent_filters_by_action == []
        assert m.intent_filters_by_category == []
        assert m.uses_features == []
        assert m.meta_data is None
        assert m.manifest_xml is None

    def test_fully_populated(self):
        from redb.models.dataclasses import APKManifest

        m = APKManifest(
            activity_count=2,
            service_count=1,
            receiver_count=1,
            provider_count=0,
            activities=["MainActivity", "SettingsActivity"],
            services=["SyncService"],
            receivers=["BootReceiver"],
            providers=[],
            exported_components=["MainActivity", "BootReceiver"],
            intent_filters_by_action=["android.intent.action.MAIN"],
            uses_features=["android.hardware.camera"],
            manifest_xml="<manifest>...</manifest>",
        )
        assert len(m.activities) == 2
        assert len(m.exported_components) == 2
        assert m.manifest_xml is not None


# ============================================================================
# APKPermission / APKPermissions
# ============================================================================

class TestAPKPermissionDataclass:

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

        p = APKPermission(
            permission_name="android.permission.CAMERA",
            protection_level="dangerous",
        )
        assert p.permission_name == "android.permission.CAMERA"
        assert p.protection_level == "dangerous"
        assert p.is_custom is False

    def test_custom_permission(self):
        from redb.models.dataclasses import APKPermission

        p = APKPermission(
            permission_name="com.example.CUSTOM_PERM",
            protection_level="signature",
            is_custom=True,
        )
        assert p.is_custom is True


class TestAPKPermissionsDataclass:

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

        p = APKPermissions(
            total_permission_count=10,
            dangerous_permission_count=3,
        )
        assert p.total_permission_count == 10
        assert p.dangerous_permission_count == 3

    def test_defaults(self):
        from redb.models.dataclasses import APKPermissions

        p = APKPermissions(
            total_permission_count=0,
            dangerous_permission_count=0,
        )
        assert p.permissions == []
        assert p.dangerous_permissions == []
        assert p.custom_permissions == []
        assert p.permission_details == []
        assert p.permhash is None

    def test_with_permission_details(self):
        from redb.models.dataclasses import APKPermission, APKPermissions

        details = [
            APKPermission("android.permission.INTERNET", "normal"),
            APKPermission("android.permission.CAMERA", "dangerous"),
        ]
        p = APKPermissions(
            total_permission_count=2,
            dangerous_permission_count=1,
            permissions=["android.permission.INTERNET", "android.permission.CAMERA"],
            dangerous_permissions=["android.permission.CAMERA"],
            permission_details=details,
            permhash="abc123def456",
        )
        assert len(p.permission_details) == 2
        assert p.permhash == "abc123def456"


# ============================================================================
# APKCertificate / APKCodeSigningInfo
# ============================================================================

class TestAPKCertificateDataclass:

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

        c = APKCertificate(
            subject="CN=Android Debug",
            issuer="CN=Android Debug",
            serial_number="1234567890",
            valid_from="2024-01-01",
            valid_to="2054-01-01",
            thumbprint_sha1="aabbccdd" * 5,
            thumbprint_sha256="aabbccdd" * 8,
        )
        assert c.subject == "CN=Android Debug"
        assert c.issuer == "CN=Android Debug"
        assert c.is_self_signed is False

    def test_optional_fields(self):
        from redb.models.dataclasses import APKCertificate

        c = APKCertificate(
            subject="CN=Test",
            issuer="CN=CA",
            serial_number="1",
            valid_from="2024-01-01",
            valid_to="2025-01-01",
            thumbprint_sha1="aa" * 20,
            thumbprint_sha256="bb" * 32,
            algorithm="SHA256withRSA",
            key_size=2048,
            is_self_signed=True,
        )
        assert c.algorithm == "SHA256withRSA"
        assert c.key_size == 2048
        assert c.is_self_signed is True


class TestAPKCodeSigningInfoDataclass:

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

        info = APKCodeSigningInfo(
            _id="abcdef1234567890" * 4,
            is_signed=True,
        )
        assert info.is_signed is True
        assert info.signature_scheme_versions == []
        assert info.number_of_certificates == 0
        assert info.x509_certificates is None
        assert info.apk_signer_subject is None
        assert info.apk_signer_issuer is None

    def test_fully_populated(self):
        from redb.models.dataclasses import APKCertificate, APKCodeSigningInfo

        cert = APKCertificate(
            subject="CN=Test",
            issuer="CN=Test",
            serial_number="1",
            valid_from="2024-01-01",
            valid_to="2025-01-01",
            thumbprint_sha1="aa" * 20,
            thumbprint_sha256="bb" * 32,
        )
        info = APKCodeSigningInfo(
            _id="cc" * 32,
            is_signed=True,
            signature_scheme_versions=[1, 2, 3],
            number_of_certificates=1,
            x509_certificates=[cert],
            apk_signer_subject="CN=Test",
            apk_signer_issuer="CN=Test",
        )
        assert len(info.signature_scheme_versions) == 3
        assert info.number_of_certificates == 1
        assert len(info.x509_certificates) == 1


# ============================================================================
# APKDexFile
# ============================================================================

class TestAPKDexFileDataclass:

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

        d = APKDexFile(
            filename="classes.dex",
            sha256="aa" * 32,
            class_count=100,
            method_count=500,
            string_count=1000,
        )
        assert d.filename == "classes.dex"
        assert d.class_count == 100
        assert d.method_count == 500
        assert d.string_count == 1000

    def test_optional_fields_defaults(self):
        from redb.models.dataclasses import APKDexFile

        d = APKDexFile(
            filename="classes2.dex",
            sha256="bb" * 32,
            class_count=0,
            method_count=0,
            string_count=0,
        )
        assert d.tlsh is None
        assert d.top_packages is None
        assert d.api_usage is None
        assert d.obfuscation_indicators is None

    def test_tlsh_populated(self):
        from redb.models.dataclasses import APKDexFile

        tlsh_value = "T1" + "A" * 68
        d = APKDexFile(
            filename="classes.dex",
            sha256="aa" * 32,
            class_count=100,
            method_count=500,
            string_count=1000,
            tlsh=tlsh_value,
        )
        assert d.tlsh == tlsh_value

    def test_with_api_usage(self):
        from redb.models.dataclasses import APKDexFile

        d = APKDexFile(
            filename="classes.dex",
            sha256="cc" * 32,
            class_count=50,
            method_count=200,
            string_count=300,
            top_packages=[{"name": "com.example", "class_count": 30}],
            api_usage={
                "crypto": ["Ljavax/crypto/Cipher;->getInstance"],
                "reflection": ["Ljava/lang/Class;->forName"],
            },
            obfuscation_indicators={"short_class_names_ratio": 0.8, "single_char_methods_ratio": 0.5},
        )
        assert len(d.api_usage) == 2
        assert d.obfuscation_indicators["short_class_names_ratio"] == 0.8


# ============================================================================
# APKResource
# ============================================================================

class TestAPKResourceDataclass:

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

        r = APKResource(
            path="res/drawable/icon.png",
            size=1024,
            sha256="dd" * 32,
            filetype_magika="png",
        )
        assert r.path == "res/drawable/icon.png"
        assert r.size == 1024
        assert r.is_suspicious is False

    def test_suspicious_resource(self):
        from redb.models.dataclasses import APKResource

        r = APKResource(
            path="assets/payload.dex",
            size=50000,
            sha256="ee" * 32,
            filetype_magika="dex",
            is_suspicious=True,
        )
        assert r.is_suspicious is True


# ============================================================================
# APKNativeLib
# ============================================================================

class TestAPKNativeLibDataclass:

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

        lib = APKNativeLib(
            abi="arm64-v8a",
            filename="libnative.so",
            size=200000,
            sha256="ff" * 32,
        )
        assert lib.abi == "arm64-v8a"
        assert lib.filename == "libnative.so"
        assert lib.is_known_packer is False

    def test_known_packer(self):
        from redb.models.dataclasses import APKNativeLib

        lib = APKNativeLib(
            abi="armeabi-v7a",
            filename="libjiagu.so",
            size=100000,
            sha256="aa" * 32,
            is_known_packer=True,
        )
        assert lib.is_known_packer is True


# ============================================================================
# APKInconsistencyTests
# ============================================================================

class TestAPKInconsistencyTestsDataclass:

    def test_all_defaults_none(self):
        from redb.models.dataclasses import APKInconsistencyTests

        t = APKInconsistencyTests()
        assert t.test_zip_bomb is None
        assert t.test_zip_duplicate_entries is None
        assert t.test_zip_path_traversal is None
        assert t.test_zip_suspicious_timestamps is None
        assert t.test_hidden_dex_files is None
        assert t.test_manifest_component_mismatch is None
        assert t.test_debuggable_release is None
        assert t.test_emulator_detection_strings is None
        assert t.test_debugger_detection is None
        assert t.test_root_detection is None

    def test_all_fields_populated(self):
        from redb.models.dataclasses import APKInconsistencyTests

        t = APKInconsistencyTests(
            test_zip_bomb=True,
            test_zip_duplicate_entries=False,
            test_zip_path_traversal=True,
            test_zip_suspicious_timestamps=False,
            test_hidden_dex_files=True,
            test_manifest_component_mismatch=False,
            test_debuggable_release=True,
            test_emulator_detection_strings=True,
            test_debugger_detection=False,
            test_root_detection=True,
        )
        assert t.test_zip_bomb is True
        assert t.test_debuggable_release is True
        # Count true values
        d = asdict(t)
        true_count = sum(1 for v in d.values() if v is True)
        assert true_count == 6

    def test_field_count(self):
        from redb.models.dataclasses import APKInconsistencyTests

        # Exactly 10 inconsistency tests per PDD specification
        assert len(fields(APKInconsistencyTests)) == 10


# ============================================================================
# Hashes dataclass — APK permhash field
# ============================================================================

class TestHashesAPKField:

    def test_permhash_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.permhash is None

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

        h = Hashes(
            md5="a", sha1="b", sha256="c", ssdeep_hash="d", tlsh_hash="e",
            permhash="abc123" * 10 + "abcd",
        )
        assert h.permhash is not None
        assert len(h.permhash) == 64


# ============================================================================
# Tag enum — APK entries
# ============================================================================

class TestAPKTagEnum:

    def test_all_apk_tags_exist(self):
        from redb.extractors.enum import Tag

        expected_tags = [
            "APK_FEATURES", "APK_MANIFEST", "APK_PERMISSIONS", "APK_SIGNATURE",
            "APK_DEX", "APK_RESOURCES", "APK_NATIVE_LIBS", "APK_INCONSISTENCY_TESTS",
        ]
        for name in expected_tags:
            assert hasattr(Tag, name), f"Tag.{name} missing"

    def test_apk_tag_values(self):
        from redb.extractors.enum import Tag

        assert Tag.APK_FEATURES.value == "apk_features"
        assert Tag.APK_MANIFEST.value == "apk_manifest"
        assert Tag.APK_PERMISSIONS.value == "apk_permissions"
        assert Tag.APK_SIGNATURE.value == "apk_signature"
        assert Tag.APK_DEX.value == "apk_dex"
        assert Tag.APK_RESOURCES.value == "apk_resources"
        assert Tag.APK_NATIVE_LIBS.value == "apk_native_libs"
        assert Tag.APK_INCONSISTENCY_TESTS.value == "apk_inconsistency_tests"