Wang-Chien Lee

366 papers A* 61A 50B 42C 7Misc 3Journal 118Unranked 69
YearRankTypeTitle / Venue / Authors
2025 A conf
AISTATS
Zixin Kuang, Meng-Fen Chiang, Wang-Chien Lee
2025 conf
KDD (2)
Ya-Wen Teng, De-Nian Yang, Yishuo Shi, Guang-Siang Lee, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2025 conf
DASFAA (2)
Bingxue Zhang, Yang Shi, Feida Zhu, Wang-Chien Lee
2025 A* conf
ICDM
Chin-Yuan Yeh, Hsi-Wen Chen, De-Nian Yang, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2025 J jnl
CoRR
Zhao Liu, Wei Liu, Huajie Zhu, Jianxing Yu, Jian Yin, Wang-Chien Lee, Shun Wang
2025 A* conf
ICDM
Yibo Huang, Zixin Kuang, Meng-Fen Chiang, Wang-Chien Lee
2025 A* conf
CCS
Guo-Wei Wong, Yi-Ting Huang, Ying-Ren Guo, Ming-Chuan Yang, Shou-De Lin, Wang-Chien Lee, Meng Chang Chen
2025 J jnl
IEEE Trans. Emerg. Top. Comput.
Yi-Cheng Chen, Mu-Ping Chang, Wang-Chien Lee
2024 J jnl
ACM Trans. Internet Techn.
Yi-Cheng Chen, Wang-Chien Lee
2024 J jnl
IEEE Trans. Emerg. Top. Comput. Intell.
Yi-Cheng Chen, Wang-Chien Lee
2024 conf
LREC/COLING
Xiaotong Feng, Meng-Fen Chiang, Wang-Chien Lee, Zixin Kuang
2024 Misc conf
SAC
Hui-Ju Hung, Wang-Chien Lee, Tao-Yang Fu, Chih-Ya Shen, Zhen Lei
2024 conf
PAKDD (2)
Hui-Ju Hung, Wang-Chien Lee, Chih-Ya Shen, Fang He, Zhen Lei
2024 A* conf
AAAI
Bay-Yuan Hsu, Chih-Ya Shen, Hao Shan Yuan, Wang-Chien Lee, De-Nian Yang
2023 A* conf
WWW
Hsi-Wen Chen, De-Nian Yang, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2023 J jnl
IEEE Trans. Knowl. Data Eng.
Huaijie Zhu, Wei Liu, Jian Yin, Libin Zheng, Xin Huang, Jianliang Xu, Wang-Chien Lee
2023 A* conf
ICDE
Huaijie Zhu, Wei Liu, Jian Yin, Ningning Cui, Jianliang Xu, Xin Huang, Wang-Chien Lee
2023 J jnl
IEEE Trans. Serv. Comput.
Cedric Parfait Kankeu Fotsing, Chih-Ya Shen, Liang-Hao Huang, Yi-Shin Chen, Wang-Chien Lee, De-Nian Yang
2023 A* conf
ICDE
Chin-Yuan Yeh, Hsi-Wen Chen, De-Nian Yang, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2023 J jnl
IEEE Trans. Knowl. Data Eng.
Fang He, Tao-Yang Fu, Wang-Chien Lee
2023 J jnl
IEEE Trans. Serv. Comput.
Huaijie Zhu, Wei Liu, Jian Yin, Jianliang Xu, Wang-Chien Lee
2022 J jnl
IEEE Trans. Knowl. Data Eng.
Chih-Ya Shen, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2022 A* conf
ICDE
Huaijie Zhu, Wei Liu, Jian Yin, Mengxiang Wang, Jianliang Xu, Xin Huang, Wang-Chien Lee
2022 J jnl
Proc. VLDB Endow.
Chih-Ya Shen, Shao-Heng Ko, Guang-Siang Lee, Wang-Chien Lee, De-Nian Yang
2022 A* conf
ICDE
Ya-Wen Teng, Yishuo Shi, De-Nian Yang, Wang-Chien Lee, Philip S. Yu, Ying-Liang Lu, Ming-Syan Chen
2022 A* conf
KDD
Zijian Huang, Meng-Fen Chiang, Wang-Chien Lee
2022 J jnl
IEEE Trans. Knowl. Data Eng.
Chih-Ya Shen, Hong-Han Shuai, De-Nian Yang, Guang-Siang Lee, Liang-Hao Huang, Wang-Chien Lee, Ming-Syan Chen
2022 J jnl
Frontiers Comput. Sci.
Na Li, Huaijie Zhu, Wenhao Lu, Ningning Cui, Wei Liu, Jian Yin, Jianliang Xu, Wang-Chien Lee
2021 A* conf
SIGIR
Fang He, Wang-Chien Lee, Tao-Yang Fu, Zhen Lei
2021 B conf
IJCNN
Xia Yang, Meng-Fen Chiang, Wang-Chien Lee, Yi Chang
2021 ed.
DASFAA (1)
Christian S. Jensen, Ee-Peng Lim, De-Nian Yang, Wang-Chien Lee, Vincent S. Tseng, Vana Kalogeraki, Jen-Wei Huang, Chih-Ya Shen
2021 ed.
DASFAA (2)
Christian S. Jensen, Ee-Peng Lim, De-Nian Yang, Wang-Chien Lee, Vincent S. Tseng, Vana Kalogeraki, Jen-Wei Huang, Chih-Ya Shen
2021 ed.
DASFAA (3)
Christian S. Jensen, Ee-Peng Lim, De-Nian Yang, Wang-Chien Lee, Vincent S. Tseng, Vana Kalogeraki, Jen-Wei Huang, Chih-Ya Shen
2021 J jnl
IEEE Trans. Knowl. Data Eng.
Zhaojing Luo, Shaofeng Cai, Gang Chen, Jinyang Gao, Wang-Chien Lee, Kee Yuan Ngiam, Meihui Zhang
2021 A* conf
ICDE
Ya-Wen Teng, Yishuo Shi, Chih-Hua Tai, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2021 J jnl
CoRR
Hsu-Chao Lai, Jui-Yi Tsai, Hong-Han Shuai, Jiun-Long Huang, Wang-Chien Lee, De-Nian Yang
2021 J jnl
ACM Trans. Intell. Syst. Technol.
Mengxiang Wang, Wang-Chien Lee, Tao-Yang Fu, Ge Yu
2021 J jnl
ACM Trans. Spatial Algorithms Syst.
Huaijie Zhu, Xiaochun Yang, Bin Wang, Wang-Chien Lee, Jian Yin, Jianliang Xu
2021 A* conf
KDD
Tao-Yang Fu, Wang-Chien Lee
2021 J jnl
Data Sci. Eng.
Bo Chen, Huaijie Zhu, Wei Liu, Jian Yin, Wang-Chien Lee, Jianliang Xu
2021 A* conf
ICDE
Hsi-Wen Chen, Hong-Han Shuai, De-Nian Yang, Wang-Chien Lee, Chuan Shi, Philip S. Yu, Ming-Syan Chen
2020 B conf
DSAA
Meng-Fen Chiang, Ee-Peng Lim, Wang-Chien Lee, Philips Kokoh Prasetyo
2020 B conf
DSAA
Yusan Lin, Peifeng Yin, Wang-Chien Lee
2020 A* conf
WWW
Hui-Ju Hung, Wang-Chien Lee, De-Nian Yang, Chih-Ya Shen, Zhen Lei, Sy-Miin Chow
2020 J jnl
CoRR
Hui-Ju Hung, Wang-Chien Lee, De-Nian Yang, Chih-Ya Shen, Zhen Lei, Sy-Miin Chow
2020 J jnl
CoRR
Ya-Wen Teng, Yishuo Shi, Chih-Hua Tai, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2020 A conf
CIKM
Hsu-Chao Lai, Jui-Yi Tsai, Hong-Han Shuai, Jiun-Long Huang, Wang-Chien Lee, De-Nian Yang
2020 J jnl
Data Min. Knowl. Discov.
Qian Ma, Wang-Chien Lee, Tao-Yang Fu, Yu Gu, Ge Yu
2020 J jnl
CoRR
Shao-Heng Ko, Hsu-Chao Lai, Hong-Han Shuai, De-Nian Yang, Wang-Chien Lee, Philip S. Yu
2020 J jnl
Proc. VLDB Endow.
Shao-Heng Ko, Hsu-Chao Lai, Hong-Han Shuai, Wang-Chien Lee, Philip S. Yu, De-Nian Yang
2020 J jnl
ACM Trans. Knowl. Discov. Data
Qian Ma, Yu Gu, Wang-Chien Lee, Ge Yu, Hongbo Liu, Xindong Wu
2020 J jnl
ACM Trans. Intell. Syst. Technol.
Tao-Yang Fu, Wang-Chien Lee
2019 A conf
CIKM
Tao-Yang Fu, Wang-Chien Lee
2019 J jnl
CoRR
Tao-Yang Fu, Wang-Chien Lee
2019 J jnl
GeoInformatica
Takahiro Hara, Wang-Chien Lee, Bin Yang
2019 conf
SIGSPATIAL/GIS
Mengxiang Wang, Wang-Chien Lee, Tao-Yang Fu, Ge Yu
2019 J jnl
IEEE Trans. Knowl. Data Eng.
Yi-Ling Chen, De-Nian Yang, Chih-Ya Shen, Wang-Chien Lee, Ming-Syan Chen
2019 A conf
CIKM
Shao-Heng Ko, Ying-Chun Lin, Hsu-Chao Lai, Wang-Chien Lee, De-Nian Yang
2019 J jnl
CoRR
Shao-Heng Ko, Ying-Chun Lin, Hsu-Chao Lai, Wang-Chien Lee, De-Nian Yang
2019 A* conf
SIGIR
Meng-Fen Chiang, Ee-Peng Lim, Wang-Chien Lee, Xavier Jayaraj Siddarth Ashok, Philips Kokoh Prasetyo
2019 A* conf
ICDE
Qian Ma, Yu Gu, Wang-Chien Lee, Ge Yu
2019 J jnl
IEEE Trans. Knowl. Data Eng.
Qian Ma, Yu Gu, Wang-Chien Lee, Ge Yu
2019 Misc conf
WISA
Huaijie Zhu, Xiaochun Yang, Bin Wang, Leixia Wang, Wang-Chien Lee
2019 A conf
CIKM
Hsu-Chao Lai, Hong-Han Shuai, De-Nian Yang, Jiun-Long Huang, Wang-Chien Lee, Philip S. Yu
2018 J jnl
IEEE Trans. Knowl. Data Eng.
Hong-Han Shuai, Chih-Ya Shen, De-Nian Yang, Yi-Feng Lan, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2018 A* conf
ICDE
Zhaojing Luo, Shaofeng Cai, Jinyang Gao, Meihui Zhang, Kee Yuan Ngiam, Gang Chen, Wang-Chien Lee
2018 A* conf
IJCAI
Jinyang Gao, Beng Chin Ooi, Yanyan Shen, Wang-Chien Lee
2018 J jnl
Trans. GIS
Hsiu-Min Chuang, Chia-Hui Chang, Wang-Chien Lee
2018 A conf
CIKM
Meng-Fen Chiang, Ee-Peng Lim, Wang-Chien Lee, Tuan-Anh Hoang
2018 ch.
Encyclopedia of Social Network Analysis and Mining. 2nd Ed.
Wang-Chien Lee, Mao Ye
2018 A* conf
WWW
Yusan Lin, Peifeng Yin, Wang-Chien Lee
2018 A conf
CIKM
Hong-Han Shuai, Yen-Chieh Lien, De-Nian Yang, Yi-Feng Lan, Wang-Chien Lee, Philip S. Yu
2018 A* conf
AAAI
Chih-Ya Shen, Cedric Parfait Kankeu Fotsing, De-Nian Yang, Yi-Shin Chen, Wang-Chien Lee
2018 J jnl
Pervasive Mob. Comput.
Yao-Chung Fan, Chih-Wei Chang, Wang-Chien Lee, Kuo-Chen Wu, Arbee L. P. Chen
2018 J jnl
IEEE Trans. Knowl. Data Eng.
Huaijie Zhu, Xiaochun Yang, Bin Wang, Wang-Chien Lee
2017 conf
IEEE BigData
Meng-Fen Chiang, Ee-Peng Lim, Wang-Chien Lee, Agus Trisnajaya Kwee
2017 J jnl
Inf. Syst.
Georgios Chatzimilioudis, Constantinos Costa, Demetrios Zeinalipour-Yazti, Wang-Chien Lee
2017 J jnl
CoRR
Jian Dai, Fei He, Wang-Chien Lee, Gang Chen, Beng Chin Ooi
2017 A* conf
ICDE
Ying Zhang, Yu-Ling Hsueh, Wang-Chien Lee, Yi-Hao Jhang
2017 J jnl
VLDB J.
Qijun Zhu, Haibo Hu, Cheng Xu, Jianliang Xu, Wang-Chien Lee
2017 A conf
CIKM
Tao-Yang Fu, Wang-Chien Lee, Zhen Lei
2017 A conf
CIKM
Yusan Lin, Peifeng Yin, Wang-Chien Lee
2017 J jnl
CoRR
Hong-Han Shuai, Yen-Chieh Lien, De-Nian Yang, Yi-Feng Lan, Wang-Chien Lee, Philip S. Yu
2017 A* conf
KDD
Chih-Ya Shen, Liang-Hao Huang, De-Nian Yang, Hong-Han Shuai, Wang-Chien Lee, Ming-Syan Chen
2017 conf
IA3@SC
Vasudevan Rengasamy, Tao-Yang Fu, Wang-Chien Lee, Kamesh Madduri
2016 J jnl
IEEE Trans. Comput. Aided Des. Integr. Circuits Syst.
Ping Chi, Wang-Chien Lee, Yuan Xie
2016 B conf
ASONAM
Yusan Lin, Wang-Chien Lee, Chung-Chou H. Chang
2016 J jnl
IEEE Trans. Knowl. Data Eng.
Georgios Chatzimilioudis, Constantinos Costa, Demetrios Zeinalipour-Yazti, Wang-Chien Lee, Evaggelia Pitoura
2016 A* conf
ICDE
Georgios Chatzimilioudis, Constantinos Costa, Demetrios Zeinalipour-Yazti, Wang-Chien Lee, Evaggelia Pitoura
2016 J jnl
IEEE Trans. Knowl. Data Eng.
Ying Zhang, Yu-Ling Hsueh, Wang-Chien Lee, Yi-Hao Jhang
2016 J jnl
Stat. Anal. Data Min.
Peifeng Yin, Qi He, Xingjie Liu, Wang-Chien Lee
2016 A* conf
WWW
Hong-Han Shuai, Chih-Ya Shen, De-Nian Yang, Yi-Feng Lan, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2016 A* conf
ICDM
Tao-Yang Fu, Zhen Lei, Wang-Chien Lee
2016 B conf
EDBT
Chen-Che Huang, Jiun-Long Huang, Tsung-Ching Liang, Jun-Zhe Wang, Wen-Yuah Shih, Wang-Chien Lee
2016 A conf
WSDM
Vineeth Rakesh, Wang-Chien Lee, Chandan K. Reddy
2016 conf
SIGMOD Conference
Huaijie Zhu, Xiaochun Yang, Bin Wang, Wang-Chien Lee
2016 A conf
ICDCS
Hui-Ju Hung, De-Nian Yang, Wang-Chien Lee
2016 J jnl
ACM Trans. Spatial Algorithms Syst.
Hui-Ju Hung, De-Nian Yang, Wang-Chien Lee
2016 J jnl
IEEE Trans. Knowl. Data Eng.
Chih-Ya Shen, De-Nian Yang, Liang-Hao Huang, Wang-Chien Lee, Ming-Syan Chen
2016 J jnl
ACM Trans. Knowl. Discov. Data
Chih-Ya Shen, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2016 A* conf
KDD
Hui-Ju Hung, Hong-Han Shuai, De-Nian Yang, Liang-Hao Huang, Wang-Chien Lee, Jian Pei, Ming-Syan Chen
2015 ch.
Applications of Social Media and Social Network Analysis
Mohammad Y. Allaho, Wang-Chien Lee
2015 J jnl
VLDB J.
Chih-Chieh Hung, Wen-Chih Peng, Wang-Chien Lee
2015 A conf
CIKM
Chih-Ya Shen, Hong-Han Shuai, De-Nian Yang, Yi-Feng Lan, Wang-Chien Lee, Philip S. Yu, Ming-Syan Chen
2015 conf
PAKDD (1)
Chih-Ya Shen, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2015 J jnl
CoRR
Chih-Ya Shen, De-Nian Yang, Wang-Chien Lee, Ming-Syan Chen
2015 A* conf
ICDM
Tao-Yang Fu, Zhen Lei, Wang-Chien Lee
2015 conf
WWW (Companion Volume)
Fei Wu, Hongjian Wang, Zhenhui Li, Wang-Chien Lee, Zhuojie Huang
2015 A* conf
WWW
Fei Wu, Zhenhui Li, Wang-Chien Lee, Hongjian Wang, Zhuojie Huang
2015 J jnl
ACM Trans. Intell. Syst. Technol.
Yi-Cheng Chen, Wen-Chih Peng, Jiun-Long Huang, Wang-Chien Lee
2015 J jnl
CoRR
Chih-Ya Shen, De-Nian Yang, Liang-Hao Huang, Wang-Chien Lee, Ming-Syan Chen
2015 conf
SBP
Yusan Lin, Heng Xu, Yilu Zhou, Wang-Chien Lee
2014 J jnl
IEEE Trans. Knowl. Data Eng.
Xin Lin, Jianliang Xu, Haibo Hu, Wang-Chien Lee
2014 J jnl
ACM Trans. Intell. Syst. Technol.
Yi-Cheng Chen, Wen-Yuan Zhu, Wen-Chih Peng, Wang-Chien Lee, Suh-Yin Lee
2014 conf
WAIM
Tiezheng Nie, Wang-Chien Lee, Derong Shen, Ge Yu, Yue Kou
2014 A conf
CIKM
Xingjie Liu, Yuanyuan Tian, Qi He, Wang-Chien Lee, John McPherson
2014 J jnl
Wirel. Networks
Chen-Che Huang, Jiun-Long Huang, Chin-Liang Tsai, Guan-Zhong Wu, Chia-Min Chen, Wang-Chien Lee
2014 A conf
CIKM
Shuting Wang, Zhen Lei, Wang-Chien Lee
2014 B conf
DSAA
Shuting Wang, Wang-Chien Lee, Zhen Lei, Xianliang Zhang, Yu-Hsuan Kuo
2014 J jnl
CoRR
Qijun Zhu, Haibo Hu, Jianliang Xu, Wang-Chien Lee
2014 A conf
CIKM
Mohammad Y. Allaho, Wang-Chien Lee
2014 J jnl
Pervasive Mob. Comput.
Ling-Yin Wei, Ya-Ting Hsu, Wen-Chih Peng, Wang-Chien Lee
2014 A conf
SDM
Peifeng Yin, Qi He, Xingjie Liu, Wang-Chien Lee
2014 ch.
Encyclopedia of Social Network Analysis and Mining
Wang-Chien Lee, Mao Ye
2014 A conf
ISLPED
Ping Chi, Wang-Chien Lee, Yuan Xie
2014 conf
PAKDD (2)
Yi-Cheng Chen, Chien-Chih Chen, Wen-Chih Peng, Wang-Chien Lee
2014 conf
PAKDD (2)
Peifeng Yin, Mao Ye, Wang-Chien Lee, Zhenhui Li
2014 A* conf
ICDM
Hongjian Wang, Zhenhui Li, Wang-Chien Lee
2014 conf
PAKDD (1)
Sooyoung Oh, Zhen Lei, Wang-Chien Lee, John Yen
2014 J jnl
IEEE Trans. Knowl. Data Eng.
Qijun Zhu, Dik Lun Lee, Wang-Chien Lee
2014 B conf
DSAA
Sooyoung Oh, Zhen Lei, Wang-Chien Lee, John Yen
2014 conf
DASFAA (1)
Yuya Sasaki, Wang-Chien Lee, Takahiro Hara, Shojiro Nishio
2014 B conf
DSAA
Hui-Ju Hung, De-Nian Yang, Wang-Chien Lee
2014 conf
BESC
Mohammad Y. Allaho, Wang-Chien Lee
2014 conf
PAKDD (1)
Peifeng Yin, Nilam Ram, Wang-Chien Lee, Conrad S. Tucker, Shashank Khandelwal, Marcel Salathé
2013 conf
ICDM Workshops
Yi-Cheng Chen, Wen-Chih Peng, Wang-Chien Lee
2013 B conf
ASONAM
Mohammad Y. Allaho, Wang-Chien Lee
2013 A conf
WSDM
Peifeng Yin, Ping Luo, Wang-Chien Lee, Min Wang
2013 A conf
CIKM
Sooyoung Oh, Zhen Lei, Wang-Chien Lee, Prasenjit Mitra, John Yen
2013 J jnl
IEEE Trans. Knowl. Data Eng.
Mao Ye, Wang-Chien Lee, Dik Lun Lee, Xingjie Liu
2013 J jnl
ACM Trans. Intell. Syst. Technol.
Ling-Yin Wei, Wen-Chih Peng, Wang-Chien Lee
2013 A conf
CIKM
Gregory Ference, Mao Ye, Wang-Chien Lee
2013 J jnl
CoRR
De-Nian Yang, Hui-Ju Hung, Wang-Chien Lee, Wei Chen
2013 A* conf
KDD
De-Nian Yang, Hui-Ju Hung, Wang-Chien Lee, Wei Chen
2013 conf
PAKDD (1)
Yi-Cheng Chen, Yu-Lun Ko, Wen-Chih Peng, Wang-Chien Lee
2013 J jnl
ACM Trans. Intell. Syst. Technol.
Josh Jia-Ching Ying, Wang-Chien Lee, Vincent S. Tseng
2013 conf
MDM (1)
Yuya Sasaki, Wang-Chien Lee, Takahiro Hara, Shojiro Nishio
2013 J jnl
IEEE Trans. Knowl. Data Eng.
Kenneth Wai-Ting Leung, Dik Lun Lee, Wang-Chien Lee
2013 A* conf
KDD
Peifeng Yin, Ping Luo, Wang-Chien Lee, Min Wang
2013 A conf
CIKM
Gregory Ference, Wang-Chien Lee, Hui-Ju Hung, De-Nian Yang
2013 conf
DASFAA (2)
Mohammad Y. Allaho, Wang-Chien Lee, De-Nian Yang
2013 J jnl
IEEE Trans. Knowl. Data Eng.
Xingjie Liu, De-Nian Yang, Mao Ye, Wang-Chien Lee
2012 J jnl
IEEE Trans. Knowl. Data Eng.
Eric Hsueh-Chan Lu, Wang-Chien Lee, Vincent Shin-Mu Tseng
2012 A conf
WSDM
Peifeng Yin, Ping Luo, Min Wang, Wang-Chien Lee
2012 B conf
MDM
Georgios Chatzimilioudis, Demetrios Zeinalipour-Yazti, Wang-Chien Lee, Marios D. Dikaiakos
2012 conf
UIC/ATC
Yao-Chung Fan, Xingjie Liu, Wang-Chien Lee, Arbee L. P. Chen
2012 J jnl
IEEE Trans. Knowl. Data Eng.
Chih-Chieh Hung, Wen-Chih Peng, Wang-Chien Lee
2012 A* conf
KDD
Xingjie Liu, Qi He, Yuanyuan Tian, Wang-Chien Lee, John McPherson, Jiawei Han
2012 A conf
CIKM
Xingjie Liu, Yuan Tian, Mao Ye, Wang-Chien Lee
2012 A* conf
SIGIR
Mao Ye, Xingjie Liu, Wang-Chien Lee
2012 A conf
CIKM
Chunyan Wang, Mao Ye, Wang-Chien Lee
2012 conf
SIGSPATIAL/GIS
Wang-Chien Lee, Weiping Si, Ling-Jyh Chen, Meng-Chang Chen
2012 B conf
MDM
Ya-Ting Hsu, Yi-Chin Pan, Ling-Yin Wei, Wen-Chih Peng, Wang-Chien Lee
2012 A conf
CIKM
De-Nian Yang, Wang-Chien Lee, Nai-Hui Chia, Mao Ye, Hui-Ju Hung
2012 A* conf
KDD
De-Nian Yang, Chih-Ya Shen, Wang-Chien Lee, Ming-Syan Chen
2012 J jnl
IEEE Trans. Knowl. Data Eng.
Mao Ye, Ken C. K. Lee, Wang-Chien Lee, Xingjie Liu, Meng-Chang Chen
2012 J jnl
IEEE Trans. Knowl. Data Eng.
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng, Yuan Tian
2012 J jnl
Mob. Networks Appl.
Ling-Jyh Chen, Yu-Song Syu, Hung-Chia Chen, Wang-Chien Lee
2011 J jnl
IEEE Trans. Parallel Distributed Syst.
Yuzhe Tang, Jianliang Xu, Shuigeng Zhou, Wang-Chien Lee, Dingxiong Deng, Yue Wang
2011 conf
COSIT
Christoph Mülligann, Krzysztof Janowicz, Mao Ye, Wang-Chien Lee
2011 A* conf
SIGIR
Kenneth Wai-Ting Leung, Dik Lun Lee, Wang-Chien Lee
2011 A* conf
ICDE
Qijun Zhu, Dik Lun Lee, Wang-Chien Lee
2011 A* conf
SIGIR
Mao Ye, Peifeng Yin, Wang-Chien Lee, Dik Lun Lee
2011 J jnl
CoRR
Mao Ye, Xingjie Liu, Wang-Chien Lee
2011 J jnl
IEEE Trans. Knowl. Data Eng.
Zhisheng Li, Ken C. K. Lee, Baihua Zheng, Wang-Chien Lee, Dik Lun Lee, Xufa Wang
2011 conf
WWW (Companion Volume)
Mao Ye, Rong Xiao, Wang-Chien Lee, Xing Xie
2011 J jnl
Data Knowl. Eng.
Ken C. K. Lee, Brandon Unger, Baihua Zheng, Wang-Chien Lee
2011 J jnl
Knowl. Inf. Syst.
Eric Hsueh-Chan Lu, Wang-Chien Lee, Vincent S. Tseng
2011 J jnl
CoRR
De-Nian Yang, Yi-Ling Chen, Wang-Chien Lee, Ming-Syan Chen
2011 J jnl
Proc. VLDB Endow.
De-Nian Yang, Yi-Ling Chen, Wang-Chien Lee, Ming-Syan Chen
2011 A* conf
KDD
Mao Ye, Dong Shou, Wang-Chien Lee, Peifeng Yin, Krzysztof Janowicz
2011 A* conf
SIGIR
Mao Ye, Rong Xiao, Wang-Chien Lee, Xing Xie
2011 ed.
GIS-LBSN
Christian S. Jensen, Wang-Chien Lee, Yu Zheng, Mohamed F. Mokbel
2011 J jnl
VLDB J.
Bo Luo, Dongwon Lee, Wang-Chien Lee, Peng Liu
2011 conf
GIS
Josh Jia-Ching Ying, Wang-Chien Lee, Tz-Chiao Weng, Vincent S. Tseng
2011 ch.
Computing with Spatial Trajectories
Wang-Chien Lee, John Krumm
2011 conf
GIS-LBSN
Josh Jia-Ching Ying, Wang-Chien Lee, Mao Ye, Ching-Yu Chen, Vincent S. Tseng
2011 conf
GIS
Mao Ye, Krzysztof Janowicz, Christoph Mülligann, Wang-Chien Lee
2010 ed.
ICPP Workshops
Wang-Chien Lee, Xin Yuan
2010 B conf
Mobile Data Management
Xingjie Liu, Jianliang Xu, Wang-Chien Lee
2010 A conf
CIKM
Yuan Tian, Qi He, Qiankun Zhao, Xingjie Liu, Wang-Chien Lee
2010 conf
ICPP Workshops
Gaurav Gupta, Wang-Chien Lee
2010 A conf
CIKM
Qiankun Zhao, Yuan Tian, Qi He, Nuria Oliver, Ruoming Jin, Wang-Chien Lee
2010 B conf
ICPP
Baihua Zheng, Wang-Chien Lee, Ken C. K. Lee, Julian Winter, Meng-Chang Chen
2010 J jnl
J. Softw.
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong, Brandon Unger, Baihua Zheng
2010 J jnl
IEEE Intell. Syst.
Flora S. Tsai, Minoru Etoh, Xing Xie, Wang-Chien Lee, Qiang Yang
2010 conf
GIS
Mao Ye, Peifeng Yin, Wang-Chien Lee
2010 conf
GIS-LBSN
Josh Jia-Ching Ying, Eric Hsueh-Chan Lu, Wang-Chien Lee, Tz-Chiao Weng, Vincent S. Tseng
2010 J jnl
IEEE Trans. Knowl. Data Eng.
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong
2010 A conf
CIKM
Peifeng Yin, Wang-Chien Lee, Ken C. K. Lee
2010 J jnl
IEEE Trans. Knowl. Data Eng.
Tao-Yang Fu, Wen-Chih Peng, Wang-Chien Lee
2010 conf
SocialCom/PASSAT
Huajing Li, Yuan Tian, Wang-Chien Lee, C. Lee Giles, Meng-Chang Chen
2010 A* conf
ICDE
Kenneth Wai-Ting Leung, Dik Lun Lee, Wang-Chien Lee
2010 A* conf
ICDE
Mao Ye, Xingjie Liu, Wang-Chien Lee, Dik Lun Lee
2010 ed.
GIS-LBSN
Xiaofang Zhou, Wang-Chien Lee, Wen-Chih Peng, Xing Xie
2010 ed.
DMSN
Demetris Zeinalipour-Yazti, Wang-Chien Lee
2010 conf
COM.Geo
Ken C. K. Lee, Mao Ye, Wang-Chien Lee
2010 A* conf
INFOCOM
Zhenjiang Li, Danny H. K. Tsang, Wang-Chien Lee
2010 J jnl
VLDB J.
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng, Huajing Li, Yuan Tian
2009 J jnl
VLDB J.
Baihua Zheng, Wang-Chien Lee, Ken C. K. Lee, Dik Lun Lee, Min Shao
2009 A* conf
SIGIR
Huajing Li, Zhisheng Li, Wang-Chien Lee, Dik Lun Lee
2009 C conf
CollaborateCom
Ling-Jyh Chen, Yu-Song Syu, Bo-Chun Wang, Wang-Chien Lee
2009 ch.
Encyclopedia of Data Warehousing and Mining
Mei Li, Wang-Chien Lee
2009 B conf
EDBT
Yunjun Gao, Baihua Zheng, Wang-Chien Lee, Gencai Chen
2009 conf
ICUIMC
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong, Brandon Unger, Baihua Zheng
2009 B conf
EDBT
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng
2009 conf
GIS
Yuan Tian, Ken C. K. Lee, Wang-Chien Lee
2009 J jnl
IEEE Trans. Dependable Secur. Comput.
Qijun Gu, Peng Liu, Wang-Chien Lee, Chao-Hsien Chu
2009 B ed.
Mobile Data Management
Yu-Chee Tseng, Peter Scheuermann, Ralf Hartmut Güting, Wang-Chien Lee, Chung-Ta King, Evaggelia Pitoura
2009 conf
GIS
Yuan Tian, Ken C. K. Lee, Wang-Chien Lee
2009 A conf
CIKM
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong, Baihua Zheng
2009 A* conf
ICDE
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong, Baihua Zheng
2009 B conf
EDBT
Bruce S. E. Chung, Wang-Chien Lee, Arbee L. P. Chen
2009 conf
IEEE SCC
Huajing Li, Maja Vukovic, Gopal Sarma Pingali, Wang-Chien Lee
2009 J jnl
Future Gener. Comput. Syst.
Wang-Chien Lee, Jianliang Xu, Jianzhong Li, Fabrizio Silvestri
2009 J jnl
IEEE Trans. Knowl. Data Eng.
Baihua Zheng, Wang-Chien Lee, Peng Liu, Dik Lun Lee, Xuhua Ding
2009 A* conf
ICDE
Yunjun Gao, Baihua Zheng, Gencai Chen, Wang-Chien Lee, Ken C. K. Lee, Qing Li
2009 J jnl
IEEE Trans. Knowl. Data Eng.
Yunjun Gao, Baihua Zheng, Gencai Chen, Wang-Chien Lee, Ken C. K. Lee, Qing Li
2009 A conf
ICDCS
Yuzhe Tang, Jianliang Xu, Shuigeng Zhou, Wang-Chien Lee
2008 J jnl
IEEE Trans. Parallel Distributed Syst.
Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2008 J jnl
IEEE Trans. Parallel Distributed Syst.
Xueyan Tang, Jianliang Xu, Wang-Chien Lee
2008 A conf
ICDCS
Yingqi Xu, Wang-Chien Lee, Gail Mitchell
2008 J jnl
Frontiers Comput. Sci. China
Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2008 A conf
CIKM
Bruce S. E. Chung, Wang-Chien Lee, Arbee L. P. Chen
2008 J jnl
Int. J. Distributed Sens. Networks
Yingqi Xu, Wang-Chien Lee, Jianliang Xu, Gail Mitchell
2008 ed.
SUTC
Mukesh Singhal, Giovanna Di Marzo Serugendo, Jeffrey J. P. Tsai, Wang-Chien Lee, Kay Römer, Yu-Chee Tseng, Han C. W. Hsiao
2008 A conf
ICDCS
Mei Li, Wang-Chien Lee
2008 B conf
MDM
Baihua Zheng, Ken C. K. Lee, Wang-Chien Lee
2008 A conf
CIKM
Yang Sun, Huajing Li, Isaac G. Councill, Wang-Chien Lee, C. Lee Giles
2008 B conf
ICPADS
Ching-Hua Yu, Wen-Chih Peng, Wang-Chien Lee
2008 conf
WIDM
Yang Sun, Huajing Li, Isaac G. Councill, Jian Huang, Wang-Chien Lee, C. Lee Giles
2008 J jnl
Wirel. Commun. Mob. Comput.
Ken C. K. Lee, Wang-Chien Lee, Sanjay Madria
2008 B conf
EDBT
Xiao Zhang, Wang-Chien Lee, Prasenjit Mitra, Baihua Zheng
2008 A conf
CIKM
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng
2008 J jnl
IEEE Trans. Knowl. Data Eng.
Ken C. K. Lee, Baihua Zheng, Wang-Chien Lee
2008 A* conf
SIGIR
Yang Song, Ziming Zhuang, Huajing Li, Qiankun Zhao, Jia Li, Wang-Chien Lee, C. Lee Giles
2008 conf
EUC (1)
Qiuxia Chen, Dik Lun Lee, Wang-Chien Lee
2008 J jnl
IEEE Trans. Parallel Distributed Syst.
Mei Li, Wang-Chien Lee, Anand Sivasubramaniam, Jing Zhao
2008 A conf
CIKM
Huajing Li, Zaiqing Nie, Wang-Chien Lee, C. Lee Giles, Ji-Rong Wen
2008 B conf
SSDBM
Ken C. K. Lee, Wang-Chien Lee, Donna J. Peuquet, Baihua Zheng
2008 J jnl
Frontiers Comput. Sci. China
Mei Li, Wang-Chien Lee, Anand Sivasubramaniam, Jizhong Zhao
2008 A conf
CIKM
Ken C. K. Lee, Josh Schiffman, Baihua Zheng, Wang-Chien Lee
2008 A conf
ICDCS
Mei Li, Ping Xia, Wang-Chien Lee
2008 J jnl
Int. J. Digit. Libr.
Huajing Li, Wang-Chien Lee, Anand Sivasubramaniam, C. Lee Giles
2007 B conf
ICWE
Huajing Li, Wang-Chien Lee, Anand Sivasubramaniam, C. Lee Giles
2007 J jnl
J. Inf. Sci. Eng.
Ya-Hui Chang, Cheng-Ta Lee, Wang-Chien Lee
2007 A* conf
INFOCOM
Yingqi Xu, Wang-Chien Lee, Jianliang Xu
2007 A* conf
VLDB
Ken C. K. Lee, Baihua Zheng, Huajing Li, Wang-Chien Lee
2007 J jnl
Comput. Commun.
Sunho Lim, Wang-Chien Lee, Guohong Cao, Chita R. Das
2007 J jnl
Int. J. Distributed Sens. Networks
Yingqi Xu, Wang-Chien Lee
2007 A conf
AsiaCCS
Padmapriya Ayyagari, Prasenjit Mitra, Dongwon Lee, Peng Liu, Wang-Chien Lee
2007 B conf
MDM
Wang-Chien Lee, Yingqi Xu
2007 J jnl
IEEE Trans. Mob. Comput.
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2007 B conf
MDM
Ross Rosemark, Wang-Chien Lee, Bhuvan Urgaonkar
2007 A conf
CIKM
Tao-Young Fu, Wen-Chih Peng, Wang-Chien Lee
2007 ed.
Infoscale
Jianzhong Li, Wang-Chien Lee, Fabrizio Silvestri
2007 J jnl
Signal Process.
Yingqi Xu, Tao-Yang Fu, Wang-Chien Lee, Julian Winter
2007 B conf
MDM
Tun-Hao You, Wen-Chih Peng, Wang-Chien Lee
2007 J jnl
J. Syst. Softw.
Ken C. K. Lee, Josh Schiffman, Baihua Zheng, Wang-Chien Lee, Hong Va Leong
2007 conf
JCDL
Huajing Li, Wang-Chien Lee, Anand Sivasubramaniam, C. Lee Giles
2007 ed.
MobiDE
Peter Scheuermann, Wang-Chien Lee, George Samaras, Dik Lun Lee
2007 J jnl
IEEE Trans. Knowl. Data Eng.
Minji Wu, Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2007 conf
MobiDE
Xiang-Yan Xiao, Wen-Chih Peng, Chih-Chieh Hung, Wang-Chien Lee
2006 conf
BNCOD
Jae-Woo Chang, Jung-Ho Um, Wang-Chien Lee
2006 J jnl
Ad Hoc Networks
Sunho Lim, Wang-Chien Lee, Guohong Cao, Chita R. Das
2006 J jnl
IEEE Trans. Knowl. Data Eng.
Jianliang Xu, Wang-Chien Lee, Xueyan Tang, Qing Gao, Shanping Li
2006 conf
SIGMOD Conference
Ken C. K. Lee, Wang-Chien Lee, Julian Winter, Baihua Zheng, Jianliang Xu
2006 B conf
EDBT
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng, Jianliang Xu
2006 conf
Infoscale
Huajing Li, Isaac G. Councill, Levent Bolelli, Ding Zhou, Yang Song, Wang-Chien Lee, Anand Sivasubramaniam, C. Lee Giles
2006 A* conf
WWW
Huajing Li, Isaac G. Councill, Wang-Chien Lee, C. Lee Giles
2006 B conf
ICNP
Mei Li, Wang-Chien Lee, Anand Sivasubramaniam
2006 conf
SUTC (1)
Yingqi Xu, Wang-Chien Lee
2006 B conf
MDM
Jianliang Xu, Baihua Zheng, Wang-Chien Lee
2006 conf
Infoscale
Huajing Li, Qingzhao Tan, Wang-Chien Lee
2006 A* conf
PerCom
Yingqi Xu, Wang-Chien Lee
2006 J jnl
VLDB J.
Baihua Zheng, Jianliang Xu, Wang-Chien Lee, Dik Lun Lee
2006 conf
SUTC (1)
Fengjun Li, Bo Luo, Peng Liu, Dongwon Lee, Prasenjit Mitra, Wang-Chien Lee, Chao-Hsien Chu
2006 conf
JCDL
Isaac G. Councill, Huajing Li, Ziming Zhuang, Sandip Debnath, Levent Bolelli, Wang-Chien Lee, Anand Sivasubramaniam, C. Lee Giles
2006 A* conf
ICDE
Minji Wu, Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2006 A* conf
ICDE
Ken C. K. Lee, Wang-Chien Lee, Hong Va Leong
2006 B conf
MDM
Wen-Chih Peng, Yu-Zen Ko, Wang-Chien Lee
2006 conf
Infoscale
Mei Li, Guanling Lee, Wang-Chien Lee, Anand Sivasubramaniam
2006 B conf
DASFAA
Ken C. K. Lee, Wang-Chien Lee, Baihua Zheng, Julian Winter
2006 A* conf
ICDE
Yingqi Xu, Wang-Chien Lee, Jianliang Xu, Gail Mitchell
2006 J jnl
IEEE Trans. Parallel Distributed Syst.
Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2006 conf
ICPS
Ken C. K. Lee, Josh Schiffman, Baihua Zheng, Wang-Chien Lee, Hong Va Leong
2006 conf
SUTC (1)
Baihua Zheng, Ken C. K. Lee, Wang-Chien Lee
2005 conf
OTM Workshops
Jae-Woo Chang, Jung-Ho Um, Wang-Chien Lee
2005 A conf
CIKM
Qingzhao Tan, Wang-Chien Lee, Baihua Zheng, Peng Liu, Dik Lun Lee
2005 A conf
ICDCS
Wang-Chien Lee, Baihua Zheng
2005 A* conf
ICDE
Wang-Chien Lee, Baihua Zheng
2005 C conf
MobiQuitous
Ross Rosemark, Wang-Chien Lee
2005 conf
XIME-P
Bo Luo, Dongwon Lee, Wang-Chien Lee, Peng Liu
2005 B conf
Mobile Data Management
Bin Liu, Wang-Chien Lee, Dik Lun Lee
2005 B conf
SECON
Jianliang Xu, Xueyan Tang, Wang-Chien Lee
2005 C conf
MobiQuitous
Julian Winter, Yingqi Xu, Wang-Chien Lee
2005 C conf
MobiQuitous
Qijun Gu, Peng Liu, Wang-Chien Lee, Chao-Hsien Chu
2005 B conf
MASS
Yingqi Xu, Wang-Chien Lee, Jianliang Xu, Gail Mitchell
2005 A* conf
ICDE
Haibo Hu, Jianliang Xu, Wing Sing Wong, Baihua Zheng, Dik Lun Lee, Wang-Chien Lee
2005 A conf
ICDCS
Bin Liu, Wang-Chien Lee, Dik Lun Lee
2004 conf
Secure Data Management
Bo Luo, Dongwon Lee, Wang-Chien Lee, Peng Liu
2004 A* conf
ICDE
Baihua Zheng, Jianliang Xu, Wang-Chien Lee
2004 C conf
MobiQuitous
Yingqi Xu, Julian Winter, Wang-Chien Lee
2004 B conf
EDBT
Baihua Zheng, Jianliang Xu, Wang-Chien Lee, Dik Lun Lee
2004 A conf
MobiSys
Jianliang Xu, Wang-Chien Lee, Xueyan Tang
2004 conf
DMSN
Julian Winter, Wang-Chien Lee
2004 J jnl
Wirel. Networks
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2004 J jnl
IEEE Trans. Knowl. Data Eng.
Jianliang Xu, Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
2004 B conf
MASS
Sunho Lim, Wang-Chien Lee, Guohong Cao, Chita R. Das
2004 B conf
Mobile Data Management
Yingqi Xu, Julian Winter, Wang-Chien Lee
2004 A conf
CIKM
Bo Luo, Dongwon Lee, Wang-Chien Lee, Peng Liu
2004 conf
WWW (Alternate Track Papers & Posters)
Jianliang Xu, Wang-Chien Lee, Jiangchuan Liu
2004 C conf
MobiQuitous
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2004 B conf
ICNP
Mei Li, Wang-Chien Lee, Anand Sivasubramaniam
2004 J jnl
Wirel. Networks
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2004 J jnl
IEEE Trans. Knowl. Data Eng.
Jianliang Xu, Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2003 conf
WWW (Posters)
Sunho Lim, Seung-Taek Park, Wang-Chien Lee, Guohong Cao, Chita R. Das, C. Lee Giles
2003 B conf
ICCCN
Sunho Lim, Wang-Chien Lee, Guohong Cao, Chita R. Das
2003 J jnl
Wirel. Networks
Yu-Chee Tseng, Sandeep K. S. Gupta, Wang-Chien Lee, Pradip K. Srimani
2003 A* conf
ICDE
Jianliang Xu, Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2003 C conf
IDEAS
Mei Li, Wang-Chien Lee, Anand Sivasubramaniam
2003 conf
ICDCS Workshops
Yingqi Xu, Wang-Chien Lee
2003 B conf
Mobile Data Management
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2003 Misc conf
SAC
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2003 A* conf
PerCom
Baihua Zheng, Wang-Chien Lee, Dik Lun Lee
2003 conf
Xsym
Dongwon Lee, Wang-Chien Lee, Peng Liu
2002 J jnl
IEEE Pervasive Comput.
Dik Lun Lee, Jianliang Xu, Baihua Zheng, Wang-Chien Lee
2002 J jnl
IEEE Trans. Computers
Pradip K. Srimani, Wang-Chien Lee, Sandeep K. S. Gupta
2001 J jnl
Distributed Parallel Databases
Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
2001 B conf
ICPP
Jianliang Xu, Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
2001 J jnl
IEEE Wirel. Commun.
Sandeep K. S. Gupta, Wang-Chien Lee, Apratim Purakayastha, Pradip K. Srimani
2001 conf
RIDE-DM
Xin Zhang, Gail Mitchell, Wang-Chien Lee, Elke A. Rundensteiner
2001 conf
SIGMOD Conference
Kajal T. Claypool, Elke A. Rundensteiner, Xin Zhang, Hong Su, Harumi A. Kuno, Wang-Chien Lee, Gail Mitchell
2001 J jnl
Mob. Networks Appl.
Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
2000 conf
ICDCS Workshop of Knowledge Discovery and Data Mining in the World-Wide Web
Wang-Chien Lee, Gail Mitchell, Xin Zhang
2000 conf
ICPP Workshops
Sandeep K. S. Gupta, Wang-Chien Lee, Pradip K. Srimani
2000 A* conf
ICDE
Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
2000 A conf
CIKM
Jianliang Xu, Qinglong Hu, Dik Lun Lee, Wang-Chien Lee
1999 J jnl
Mob. Networks Appl.
Wang-Chien Lee, Qinglong Hu, Dik Lun Lee
1999 A conf
CIKM
Qinglong Hu, Wang-Chien Lee, Dik Lun Lee
1999 ed.
MDA
Hong Va Leong, Wang-Chien Lee, Bo Li, Li Yin
1999 conf
MDA
Wang-Chien Lee, Johnson Lee, Karen E. Huff
1999 A* conf
MobiCom
Qinglong Hu, Dik Lun Lee, Wang-Chien Lee
1999 J jnl
IEEE Data Eng. Bull.
Sandra Heiler, Wang-Chien Lee, Gail Mitchell
1999 J jnl
Wirel. Networks
Wang-Chien Lee, Dik Lun Lee
1998 B conf
NOMS
Wang-Chien Lee, Gail Mitchell
1998 J jnl
IEEE Trans. Knowl. Data Eng.
Wang-Chien Lee, Dik Lun Lee
1998 conf
ER Workshops
Qinglong Hu, Dik Lun Lee, Wang-Chien Lee
1998 conf
FODO
Dik Lun Lee, Qinglong Hu, Wang-Chien Lee
1998 A conf
ICDCS
Qinglong Hu, Dik Lun Lee, Wang-Chien Lee
1998 conf
ER Workshops
Wang-Chien Lee
1997 A conf
HPDC
Wang-Chien Lee, Qinglong Hu, Dik Lun Lee
1996 J jnl
Distributed Parallel Databases
Wang-Chien Lee, Dik Lun Lee
1995 B conf
DASFAA
Wang-Chien Lee, Dik Lun Lee
1995 conf
RIDE-DOM
Wang-Chien Lee, Dik Lun Lee
1994 A conf
CIKM
Dik Lun Lee, Wang-Chien Lee
tests/unit/test_apk_extractors.py
← Index tests/unit/test_apk_extractors.py python
"""
Unit tests for APK extractors.

Tests tag(), get_clickhouse_table(), extract(), and prepare_export_data()
for all 8 APK extractors. Uses mocked androguard APK objects.
"""
import pytest
import os
import hashlib
import tempfile
import zipfile
from dataclasses import asdict
from unittest.mock import MagicMock, patch, PropertyMock

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


# ============================================================================
# Helpers
# ============================================================================

def _create_fake_apk(tmp_path, files=None):
    """Create a minimal valid ZIP file that pretends to be an APK.

    Args:
        tmp_path: Directory to write the fake APK into.
        files: Dict of {filename: content_bytes} to include in the ZIP.

    Returns:
        Path to the fake APK file.
    """
    apk_path = os.path.join(tmp_path, "test.apk")
    default_files = {
        "AndroidManifest.xml": b"<manifest/>",
        "classes.dex": b"dex\n035\x00" + b"\x00" * 100,
        "res/drawable/icon.png": b"\x89PNG" + b"\x00" * 50,
    }
    if files:
        default_files.update(files)

    with zipfile.ZipFile(apk_path, "w") as zf:
        for name, data in default_files.items():
            zf.writestr(name, data)
    return apk_path


def _make_mock_apk():
    """Create a mock androguard APK object with common return values."""
    mock_apk = MagicMock()
    mock_apk.get_package.return_value = "com.example.test"
    mock_apk.get_app_name.return_value = "Test App"
    mock_apk.get_androidversion_code.return_value = "10"
    mock_apk.get_androidversion_name.return_value = "1.2.3"
    mock_apk.get_min_sdk_version.return_value = "21"
    mock_apk.get_target_sdk_version.return_value = "33"
    mock_apk.get_effective_target_sdk_version.return_value = "33"
    mock_apk.get_main_activity.return_value = "com.example.test.MainActivity"
    mock_apk.get_attribute_value.return_value = None
    mock_apk.get_libraries.return_value = []
    mock_apk.get_files.return_value = [
        "AndroidManifest.xml", "classes.dex",
        "res/drawable/icon.png", "lib/armeabi-v7a/libnative.so",
        "assets/data.bin",
    ]
    mock_apk.get_permissions.return_value = [
        "android.permission.INTERNET",
        "android.permission.CAMERA",
    ]
    mock_apk.get_declared_permissions.return_value = {}
    mock_apk.get_activities.return_value = ["com.example.test.MainActivity"]
    mock_apk.get_services.return_value = ["com.example.test.MyService"]
    mock_apk.get_receivers.return_value = ["com.example.test.BootReceiver"]
    mock_apk.get_providers.return_value = []
    mock_apk.get_uses_implied_permission_list.return_value = []
    mock_apk.is_valid_APK.return_value = True
    mock_apk.get_certificates.return_value = []
    mock_apk.get_certificates_v1.return_value = []
    mock_apk.get_certificates_v2.return_value = []
    mock_apk.get_certificates_v3.return_value = []
    mock_apk.get_signature_names.return_value = []
    mock_apk.is_signed_v1.return_value = True
    mock_apk.is_signed_v2.return_value = True
    mock_apk.is_signed_v3.return_value = False
    return mock_apk


@pytest.fixture
def fake_apk_env(tmp_path):
    """Create a fake APK file and mock APK object."""
    apk_path = _create_fake_apk(str(tmp_path))
    mock_apk = _make_mock_apk()
    mock_logger = MagicMock()
    mock_exporters = [MagicMock()]
    return apk_path, mock_apk, mock_logger, mock_exporters


# ============================================================================
# APKFeaturesExtractor
# ============================================================================

class TestAPKFeaturesExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_features"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_features"

    def test_extract_returns_dataclass(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor
        from redb.models.dataclasses import APKFeatures

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert isinstance(result, APKFeatures)
        assert result.package_name == "com.example.test"
        assert result.app_name == "Test App"
        assert result.version_code == 10
        assert result.version_name == "1.2.3"
        assert result.min_sdk_version == 21
        assert result.target_sdk_version == 33
        assert result.main_activity == "com.example.test.MainActivity"

    def test_extract_detects_native_code(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result.has_native_code is True
        assert result.has_assets is True

    def test_extract_invalid_apk_returns_none(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.is_valid_APK.return_value = False
        # APKExtractor sets self.apk to the mock_apk directly; _is_valid_apk checks self.apk is not None
        # For invalid APK, set apk to None
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=None)
        # Override _is_valid_apk to simulate parsing failure
        ext.apk = None
        result = ext.extract()
        assert result is None

    def test_extract_handles_missing_version_code(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.get_androidversion_code.return_value = None
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result.version_code == 0

    def test_prepare_export_data_clickhouse(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        ext.extract()
        result = ext.prepare_export_data("ClickHouseExporter")
        assert result is not None
        data, column_names, column_type_names = result
        assert "sha256" in column_names
        assert "package_name" in column_names
        assert "analysis_date" in column_names
        assert len(column_names) == len(column_type_names)
        assert len(data) == 1  # One row
        assert len(data[0]) == len(column_names)

    def test_prepare_export_data_no_extract(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        # Don't call extract() first
        result = ext.prepare_export_data("ClickHouseExporter")
        assert result is None


# ============================================================================
# APKManifestExtractor
# ============================================================================

class TestAPKManifestExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_manifest import APKManifestExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKManifestExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_manifest"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_manifest import APKManifestExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKManifestExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_manifest"

    def test_extract_returns_dataclass(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_manifest import APKManifestExtractor
        from redb.models.dataclasses import APKManifest

        apk_path, mock_apk, logger, exporters = fake_apk_env
        # Setup intent filter mocking
        mock_apk.get_intent_filters.return_value = {}
        ext = APKManifestExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert isinstance(result, APKManifest)
        assert result.activity_count == 1
        assert result.service_count == 1
        assert result.receiver_count == 1
        assert result.provider_count == 0

    def test_extract_counts_components(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_manifest import APKManifestExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.get_activities.return_value = ["A1", "A2", "A3"]
        mock_apk.get_services.return_value = ["S1", "S2"]
        mock_apk.get_intent_filters.return_value = {}
        ext = APKManifestExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result.activity_count == 3
        assert result.service_count == 2


# ============================================================================
# APKPermissionsExtractor
# ============================================================================

class TestAPKPermissionsExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_permissions import APKPermissionsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKPermissionsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_permissions"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_permissions import APKPermissionsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKPermissionsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_permissions"

    def test_extract_returns_dataclass(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_permissions import APKPermissionsExtractor
        from redb.models.dataclasses import APKPermissions

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKPermissionsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert isinstance(result, APKPermissions)
        assert result.total_permission_count == 2
        assert "android.permission.INTERNET" in result.permissions
        assert "android.permission.CAMERA" in result.permissions

    def test_extract_classifies_dangerous(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_permissions import APKPermissionsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKPermissionsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        # CAMERA is dangerous, INTERNET is normal
        assert result.dangerous_permission_count >= 1
        assert "android.permission.CAMERA" in result.dangerous_permissions

    def test_extract_no_permissions(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_permissions import APKPermissionsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.get_permissions.return_value = []
        ext = APKPermissionsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result.total_permission_count == 0
        assert result.dangerous_permission_count == 0


# ============================================================================
# APKSignatureExtractor
# ============================================================================

class TestAPKSignatureExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_signature import APKSignatureExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKSignatureExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_signature"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_signature import APKSignatureExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKSignatureExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_signature"

    def test_extract_unsigned_apk(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_signature import APKSignatureExtractor
        from redb.models.dataclasses import APKCodeSigningInfo

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.is_signed_v1.return_value = False
        mock_apk.is_signed_v2.return_value = False
        mock_apk.is_signed_v3.return_value = False
        ext = APKSignatureExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert isinstance(result, APKCodeSigningInfo)

    def test_extract_detects_signature_schemes(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_signature import APKSignatureExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.is_signed_v1.return_value = True
        mock_apk.is_signed_v2.return_value = True
        mock_apk.is_signed_v3.return_value = True
        ext = APKSignatureExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert 1 in result.signature_scheme_versions
        assert 2 in result.signature_scheme_versions
        assert 3 in result.signature_scheme_versions

    def test_certificate_subject_uses_short_names(self, fake_apk_env):
        """Ensure subject/issuer use RFC 4514 short names (CN=, O=) not long names."""
        from unittest.mock import MagicMock
        from asn1crypto import x509
        from redb.extractors.apk_extractors.apk_signature import APKSignatureExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env

        # Build a real asn1crypto Name so the conversion is exercised
        subject_name = x509.Name.build({
            'country_name': 'US',
            'state_or_province_name': 'California',
            'organization_name': 'Android',
            'common_name': 'Android Debug',
        })

        mock_cert = MagicMock()
        mock_cert.subject = subject_name
        mock_cert.issuer = subject_name
        mock_cert.serial_number = 12345
        mock_cert.not_valid_before = '2020-01-01 00:00:00'
        mock_cert.not_valid_after = '2030-01-01 00:00:00'
        mock_cert.hash_algo = 'sha256'
        mock_cert.public_key.bit_size = 2048
        mock_cert.dump.return_value = b'fake_cert_der_data'

        mock_apk.is_signed_v1.return_value = False
        mock_apk.is_signed_v2.return_value = True
        mock_apk.is_signed_v3.return_value = False
        mock_apk.get_certificates_v2.return_value = [mock_cert]

        ext = APKSignatureExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert result.apk_signer_subject is not None
        assert 'CN=' in result.apk_signer_subject
        assert 'O=' in result.apk_signer_subject
        assert 'Common Name' not in result.apk_signer_subject
        assert 'Organization' not in result.apk_signer_subject

        # Also check the certificate list
        assert len(result.x509_certificates) == 1
        cert = result.x509_certificates[0]
        assert 'CN=' in cert.subject
        assert 'Common Name' not in cert.subject


# ============================================================================
# APKDexExtractor
# ============================================================================

class TestAPKDexExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_dex"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_dex"

    def test_extract_returns_list(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        # Mock DEX data access
        mock_apk.get_dex_names.return_value = ["classes.dex"]
        mock_apk.get_all_dex.return_value = [b"dex\n035\x00" + b"\x00" * 100]

        # Mock the androguard DEX parser
        mock_dex_class = MagicMock()
        mock_dex_instance = MagicMock()
        mock_dex_instance.get_classes.return_value = []
        mock_dex_instance.get_methods.return_value = []
        mock_dex_instance.get_strings.return_value = []
        mock_dex_class.return_value = mock_dex_instance

        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        with patch.dict('sys.modules', {'androguard.core.dex': MagicMock(DEX=mock_dex_class)}):
            result = ext.extract()

        assert result is not None
        assert isinstance(result, list)
        assert len(result) == 1
        assert result[0].filename == "classes.dex"

    def test_extract_computes_tlsh(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        # Need enough data for TLSH (>50 bytes of varied content)
        import os
        dex_data = os.urandom(256)
        mock_apk.get_dex_names.return_value = ["classes.dex"]
        mock_apk.get_all_dex.return_value = [dex_data]

        mock_dex_class = MagicMock()
        mock_dex_instance = MagicMock()
        mock_dex_instance.get_classes.return_value = []
        mock_dex_instance.get_methods.return_value = []
        mock_dex_instance.get_strings.return_value = []
        mock_dex_instance.get_encoded_methods.return_value = []
        mock_dex_class.return_value = mock_dex_instance

        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        with patch.dict('sys.modules', {'androguard.core.dex': MagicMock(DEX=mock_dex_class)}):
            result = ext.extract()

        assert result is not None
        assert result[0].tlsh is not None
        assert result[0].tlsh.startswith("T1")

    def test_extract_tlsh_none_for_small_dex(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        # Too small / uniform for TLSH
        dex_data = b"\x00" * 10
        mock_apk.get_dex_names.return_value = ["classes.dex"]
        mock_apk.get_all_dex.return_value = [dex_data]

        mock_dex_class = MagicMock()
        mock_dex_instance = MagicMock()
        mock_dex_instance.get_classes.return_value = []
        mock_dex_instance.get_methods.return_value = []
        mock_dex_instance.get_strings.return_value = []
        mock_dex_instance.get_encoded_methods.return_value = []
        mock_dex_class.return_value = mock_dex_instance

        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        with patch.dict('sys.modules', {'androguard.core.dex': MagicMock(DEX=mock_dex_class)}):
            result = ext.extract()

        assert result is not None
        # TLSH returns empty string for insufficient data, which we convert to None
        assert result[0].tlsh is None

    def test_prepare_export_clickhouse_includes_tlsh(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor
        from redb.models.dataclasses import APKDexFile

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        # Manually set dex_files to test export
        ext.dex_files = [APKDexFile(
            filename="classes.dex",
            sha256="aa" * 32,
            class_count=10,
            method_count=50,
            string_count=100,
            tlsh="T1" + "B" * 68,
        )]

        result = ext.prepare_export_data("ClickHouseExporter")
        assert result is not None
        dex_export = result['dex']
        assert 'dex_tlsh' in dex_export['column_names']
        tlsh_idx = dex_export['column_names'].index('dex_tlsh')
        assert dex_export['data'][0][tlsh_idx] == "T1" + "B" * 68
        assert len(dex_export['column_names']) == len(dex_export['column_type_names'])

    def test_extract_no_dex_returns_none(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_dex import APKDexExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        mock_apk.get_dex_names.return_value = []
        mock_apk.get_all_dex.return_value = []
        ext = APKDexExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result is None


# ============================================================================
# APKResourceExtractor
# ============================================================================

class TestAPKResourceExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKResourceExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_resources"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKResourceExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_resources"

    def test_extract_returns_dict(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKResourceExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        # Returns dict with 'resources' key containing list of APKResource
        assert result is None or isinstance(result, dict)
        if result:
            assert "resources" in result
            assert "total_resource_count" in result
            assert isinstance(result["resources"], list)


# ============================================================================
# APKResourceExtractor — _identify_android_format
# ============================================================================

class TestIdentifyAndroidFormat:
    """Unit tests for Android-specific binary format magic detection."""

    def _make_extractor(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor
        apk_path, mock_apk, logger, exporters = fake_apk_env
        return APKResourceExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

    def test_axml_magic(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'\x03\x00\x08\x00' + b'\x00' * 12
        assert ext._identify_android_format(header) == "android_binary_xml"

    def test_arsc_magic(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'\x02\x00\x0c\x00' + b'\x00' * 12
        assert ext._identify_android_format(header) == "android_resource_table"

    def test_art_prof_magic(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'pro\x00' + b'\x00' * 12
        assert ext._identify_android_format(header) == "android_art_profile"

    def test_art_profm_magic(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'prm\x00' + b'\x00' * 12
        assert ext._identify_android_format(header) == "android_art_profile_metadata"

    def test_unknown_magic_returns_none(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'\xff\xff\xff\xff' + b'\x00' * 12
        assert ext._identify_android_format(header) is None

    def test_short_header_returns_none(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._identify_android_format(b'\x03\x00') is None
        assert ext._identify_android_format(b'') is None

    def test_png_magic_not_matched(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        header = b'\x89PNG\r\n\x1a\n' + b'\x00' * 8
        assert ext._identify_android_format(header) is None


# ============================================================================
# APKResourceExtractor — _is_suspicious_resource
# ============================================================================

class TestIsSuspiciousResource:
    """Unit tests for the layered suspicious resource classification."""

    def _make_extractor(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor
        apk_path, mock_apk, logger, exporters = fake_apk_env
        return APKResourceExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

    # ── Layer 1: Allowlisted paths ──────────────────────────────────────

    def test_allowlisted_baseline_prof_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/dexopt/baseline.prof",
            magika_type="unknown", entropy=7.9,
            android_type=None,
        ) is False

    def test_allowlisted_baseline_profm_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/dexopt/baseline.profm",
            magika_type="unknown", entropy=7.9,
            android_type=None,
        ) is False

    # ── Layer 2: Android-specific formats → always benign ───────────────

    def test_axml_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/layout/activity_main.xml",
            magika_type="gzip", entropy=6.5,
            android_type="android_binary_xml",
        ) is False

    def test_arsc_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/values/resources.arsc",
            magika_type="unknown", entropy=7.2,
            android_type="android_resource_table",
        ) is False

    def test_art_profile_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/custom/baseline.prof",
            magika_type="unknown", entropy=7.8,
            android_type="android_art_profile",
        ) is False

    def test_art_profile_metadata_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/other/baseline.profm",
            magika_type="unknown", entropy=7.5,
            android_type="android_art_profile_metadata",
        ) is False

    # ── Layer 3: Image extension / Magika type mismatch ─────────────────

    def test_fake_png_extension_with_non_image_content_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/raw/payload.png",
            magika_type="zip", entropy=7.2,
            android_type=None,
        ) is True

    def test_fake_jpg_extension_with_unknown_high_entropy_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/data.jpg",
            magika_type="unknown", entropy=6.5,
            android_type=None,
        ) is True

    def test_image_extension_mismatch_low_entropy_not_suspicious(self, fake_apk_env):
        """Tiny/low-entropy files with image extensions shouldn't be flagged."""
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/drawable/tiny.png",
            magika_type="unknown", entropy=3.0,
            android_type=None,
        ) is False

    # ── Layer 4: Magika-confirmed images → benign ───────────────────────

    def test_confirmed_png_high_entropy_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/drawable/photo.png",
            magika_type="png", entropy=7.95,
            android_type=None,
        ) is False

    def test_confirmed_webp_high_entropy_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/drawable/image.webp",
            magika_type="webp", entropy=7.99,
            android_type=None,
        ) is False

    def test_confirmed_jpeg_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/photos/bg.jpg",
            magika_type="jpeg", entropy=7.9,
            android_type=None,
        ) is False

    # ── Layer 5: Known suspicious file types ────────────────────────────

    def test_elf_in_assets_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/payload",
            magika_type="elf", entropy=5.0,
            android_type=None,
        ) is True

    def test_dex_in_assets_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/classes.dex",
            magika_type="dex", entropy=5.5,
            android_type=None,
        ) is True

    def test_shell_script_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/run.sh",
            magika_type="shell", entropy=4.0,
            android_type=None,
        ) is True

    def test_zip_in_assets_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/data.zip",
            magika_type="zip", entropy=7.5,
            android_type=None,
        ) is True

    def test_jar_in_assets_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/plugin.jar",
            magika_type="jar", entropy=6.0,
            android_type=None,
        ) is True

    def test_lzma_in_assets_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/blob.lzma",
            magika_type="lzma", entropy=7.9,
            android_type=None,
        ) is True

    # ── Layer 6: High-entropy unrecognized blobs ────────────────────────

    def test_unknown_type_high_entropy_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/xyzdata",
            magika_type="unknown", entropy=7.5,
            android_type=None,
        ) is True

    def test_empty_type_high_entropy_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/blob.dat",
            magika_type="empty", entropy=7.2,
            android_type=None,
        ) is True

    def test_unknown_type_low_entropy_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/config.dat",
            magika_type="unknown", entropy=4.5,
            android_type=None,
        ) is False

    # ── Layer 7: Extreme entropy on non-image recognized types ──────────

    def test_xml_extreme_entropy_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/raw/config.xml",
            magika_type="xml", entropy=7.9,
            android_type=None,
        ) is True

    def test_txt_extreme_entropy_is_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/readme.txt",
            magika_type="txt", entropy=7.86,
            android_type=None,
        ) is True

    def test_xml_normal_entropy_not_suspicious(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="res/raw/config.xml",
            magika_type="xml", entropy=4.0,
            android_type=None,
        ) is False

    # ── Benign types that should NOT be flagged ─────────────────────────

    def test_html_not_in_suspicious_types(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/index.html",
            magika_type="html", entropy=5.0,
            android_type=None,
        ) is False

    def test_javascript_not_in_suspicious_types(self, fake_apk_env):
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/app.js",
            magika_type="javascript", entropy=5.0,
            android_type=None,
        ) is False

    def test_sqlite_not_in_suspicious_types(self, fake_apk_env):
        """sqlite was intentionally excluded — too many legitimate uses."""
        ext = self._make_extractor(fake_apk_env)
        assert ext._is_suspicious_resource(
            path="assets/data.db",
            magika_type="sqlite", entropy=5.0,
            android_type=None,
        ) is False


# ============================================================================
# APKResourceExtractor — integration with extract()
# ============================================================================

class TestAPKResourceExtractorIntegration:
    """Integration tests: craft ZIP contents and verify end-to-end classification."""

    def test_extract_flags_elf_in_assets(self, tmp_path):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path = _create_fake_apk(str(tmp_path), {
            "assets/payload.bin": b"\x7fELF" + b"\x00" * 100,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()

        # Mock Magika to return "elf" for the payload — real Magika needs
        # a valid ELF structure, but we control classification in unit tests.
        mock_magika = MagicMock()
        mock_magika.identify_bytes.return_value = MagicMock(
            output=MagicMock(label="elf")
        )

        ext = APKResourceExtractor(apk_path, logger, exporters=[MagicMock()], apk=mock_apk)
        with patch("magika.Magika", return_value=mock_magika):
            result = ext.extract()
        assert result is not None
        assert result["suspicious_file_count"] >= 1
        sus_paths = [s.path for s in result["suspicious_files"]]
        assert "assets/payload.bin" in sus_paths

    def test_extract_does_not_flag_normal_png(self, tmp_path):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path = _create_fake_apk(str(tmp_path), {
            "res/drawable/icon.png": b"\x89PNG\r\n\x1a\n" + b"\x00" * 50,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()

        ext = APKResourceExtractor(apk_path, logger, exporters=[MagicMock()], apk=mock_apk)
        result = ext.extract()
        assert result is not None
        sus_paths = [s.path for s in result["suspicious_files"]]
        assert "res/drawable/icon.png" not in sus_paths

    def test_extract_stores_android_type_override(self, tmp_path):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        # AXML magic — Magika would likely misclassify, but stored_type
        # should be "android_binary_xml"
        axml_data = b'\x03\x00\x08\x00' + b'\x00' * 50
        apk_path = _create_fake_apk(str(tmp_path), {
            "res/layout/main.xml": axml_data,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()

        ext = APKResourceExtractor(apk_path, logger, exporters=[MagicMock()], apk=mock_apk)
        result = ext.extract()
        assert result is not None
        axml_resources = [r for r in result["resources"]
                          if r.path == "res/layout/main.xml"]
        assert len(axml_resources) == 1
        assert axml_resources[0].filetype_magika == "android_binary_xml"
        assert axml_resources[0].is_suspicious is False

    def test_extract_skips_non_res_non_assets(self, tmp_path):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path = _create_fake_apk(str(tmp_path), {
            "lib/armeabi-v7a/libnative.so": b"\x7fELF" + b"\x00" * 50,
            "META-INF/MANIFEST.MF": b"Manifest-Version: 1.0\n",
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()

        ext = APKResourceExtractor(apk_path, logger, exporters=[MagicMock()], apk=mock_apk)
        result = ext.extract()
        if result:
            res_paths = [r.path for r in result["resources"]]
            assert "lib/armeabi-v7a/libnative.so" not in res_paths
            assert "META-INF/MANIFEST.MF" not in res_paths

    def test_prepare_export_includes_suspicious_flag(self, tmp_path):
        from redb.extractors.apk_extractors.apk_resources import APKResourceExtractor

        apk_path = _create_fake_apk(str(tmp_path), {
            "assets/evil.bin": b"\x7fELF" + b"\x00" * 100,
            "res/drawable/ok.png": b"\x89PNG\r\n\x1a\n" + b"\x00" * 50,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()

        # Map filenames to Magika labels so the ELF payload gets flagged
        def _magika_side_effect(data):
            if data[:4] == b"\x7fELF":
                return MagicMock(output=MagicMock(label="elf"))
            return MagicMock(output=MagicMock(label="png"))

        mock_magika = MagicMock()
        mock_magika.identify_bytes.side_effect = _magika_side_effect

        ext = APKResourceExtractor(apk_path, logger, exporters=[MagicMock()], apk=mock_apk)
        with patch("magika.Magika", return_value=mock_magika):
            ext.extract()
        result = ext.prepare_export_data("ClickHouseExporter")
        assert result is not None
        data, col_names, col_types = result
        assert "is_suspicious" in col_names
        sus_idx = col_names.index("is_suspicious")
        # At least one row should have is_suspicious=1
        sus_values = [row[sus_idx] for row in data]
        assert 1 in sus_values


# ============================================================================
# APKNativeLibExtractor
# ============================================================================

class TestAPKNativeLibExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_native_libs import APKNativeLibExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKNativeLibExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_native_libs"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_native_libs import APKNativeLibExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKNativeLibExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_native_libs"

    def test_extract_finds_native_libs(self, tmp_path):
        from redb.extractors.apk_extractors.apk_native_libs import APKNativeLibExtractor
        from redb.models.dataclasses import APKNativeLib

        # Create APK with a native lib inside
        apk_path = _create_fake_apk(str(tmp_path), {
            "lib/armeabi-v7a/libnative.so": b"\x7fELF" + b"\x00" * 100,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()
        exporters = [MagicMock()]

        ext = APKNativeLibExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result is not None
        assert isinstance(result, dict)
        assert "native_libs" in result
        assert len(result["native_libs"]) >= 1
        assert isinstance(result["native_libs"][0], APKNativeLib)
        assert result["native_libs"][0].abi == "armeabi-v7a"

    def test_extract_detects_packer_libs(self, tmp_path):
        from redb.extractors.apk_extractors.apk_native_libs import APKNativeLibExtractor

        # Create APK with a known packer lib
        apk_path = _create_fake_apk(str(tmp_path), {
            "lib/armeabi-v7a/libjiagu.so": b"\x7fELF" + b"\x00" * 50,
            "lib/armeabi-v7a/libnormal.so": b"\x7fELF" + b"\x00" * 50,
        })
        mock_apk = _make_mock_apk()
        logger = MagicMock()
        exporters = [MagicMock()]

        ext = APKNativeLibExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result is not None
        packer_libs = [lib for lib in result["native_libs"] if lib.is_known_packer]
        assert len(packer_libs) >= 1  # libjiagu.so is a known packer

    def test_extract_no_native_libs(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_native_libs import APKNativeLibExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        # The fake APK has no lib/*.so files
        mock_apk.get_files.return_value = ["classes.dex", "AndroidManifest.xml"]
        ext = APKNativeLibExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        assert result is None


# ============================================================================
# APKInconsistencyTestsExtractor
# ============================================================================

class TestAPKInconsistencyTestsExtractor:

    def test_tag(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_inconsistency_tests import APKInconsistencyTestsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKInconsistencyTestsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.tag() == "apk_inconsistency_tests"

    def test_clickhouse_table(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_inconsistency_tests import APKInconsistencyTestsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKInconsistencyTestsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext.get_clickhouse_table() == "redb_apk_inconsistency_tests"

    def test_extract_returns_dataclass(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_inconsistency_tests import APKInconsistencyTestsExtractor
        from redb.models.dataclasses import APKInconsistencyTests

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKInconsistencyTestsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()

        assert isinstance(result, APKInconsistencyTests)

    def test_extract_clean_apk_no_anomalies(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_inconsistency_tests import APKInconsistencyTestsExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKInconsistencyTestsExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        result = ext.extract()
        # A clean APK should have mostly False values
        assert result.test_zip_bomb is not None  # Should be set (True or False)


# ============================================================================
# APK workers.py integration — module registry
# ============================================================================

class TestAPKModuleRegistry:

    def test_all_apk_modules_in_registry(self):
        from redb.workers import get_module_by_name

        apk_modules = [
            "APKFeaturesExtractor",
            "APKManifestExtractor",
            "APKPermissionsExtractor",
            "APKSignatureExtractor",
            "APKDexExtractor",
            "APKResourceExtractor",
            "APKNativeLibExtractor",
            "APKInconsistencyTestsExtractor",
        ]
        for name in apk_modules:
            module_class = get_module_by_name(name)
            assert module_class is not None, f"{name} not found in module registry"

    def test_apk_module_classes_correct(self):
        from redb.workers import get_module_by_name
        from redb.extractors.apk_extractors import (
            APKFeaturesExtractor,
            APKManifestExtractor,
            APKPermissionsExtractor,
            APKSignatureExtractor,
            APKDexExtractor,
            APKResourceExtractor,
            APKNativeLibExtractor,
            APKInconsistencyTestsExtractor,
        )

        assert get_module_by_name("APKFeaturesExtractor") is APKFeaturesExtractor
        assert get_module_by_name("APKManifestExtractor") is APKManifestExtractor
        assert get_module_by_name("APKPermissionsExtractor") is APKPermissionsExtractor
        assert get_module_by_name("APKSignatureExtractor") is APKSignatureExtractor
        assert get_module_by_name("APKDexExtractor") is APKDexExtractor
        assert get_module_by_name("APKResourceExtractor") is APKResourceExtractor
        assert get_module_by_name("APKNativeLibExtractor") is APKNativeLibExtractor
        assert get_module_by_name("APKInconsistencyTestsExtractor") is APKInconsistencyTestsExtractor


# ============================================================================
# APK filetype guard — workers.py dispatch
# ============================================================================

class TestAPKWorkerDispatch:

    def test_apk_excluded_from_die_guard(self):
        """APK filetype should be in the exclusion set alongside macho for DIE/BasicProperties/Hash."""
        import redb.workers as workers_mod
        import inspect

        source = inspect.getsource(workers_mod.process_binary_file)
        # The guards should exclude "apk" from DIE, BasicProperties, HashExtractor.
        # The exact tuple may grow as new text-based formats are added (e.g.
        # "javascript"), so we check that "apk" is present in a filetype
        # exclusion guard rather than matching the full tuple literally.
        assert 'filetype not in ("macho", "apk"' in source

    def test_apk_dispatch_branch_exists(self):
        """The APK dispatch branch should exist and registry should provide all APK extractors."""
        import inspect
        import redb.workers as workers_mod
        from redb.extractor_registry import get_filetype_modules

        # Verify the APK branch exists in process_binary_file
        source = inspect.getsource(workers_mod.process_binary_file)
        assert 'elif filetype == "apk"' in source

        # Verify all APK extractors are registered and loadable
        apk_modules = get_filetype_modules("apk")
        apk_names = {m.__name__ for m in apk_modules}
        for expected in [
            "APKFeaturesExtractor", "APKManifestExtractor",
            "APKPermissionsExtractor", "APKSignatureExtractor",
            "APKDexExtractor", "APKResourceExtractor",
            "APKNativeLibExtractor", "APKInconsistencyTestsExtractor",
        ]:
            assert expected in apk_names, f"{expected} not in APK registry"

    def test_apk_dispatch_runs_basic_and_hash(self):
        """The APK dispatch branch should run BasicPropertiesExtractor and HashExtractor."""
        import redb.workers as workers_mod
        import inspect

        source = inspect.getsource(workers_mod.process_binary_file)
        # Find the apk block
        apk_idx = source.index('elif filetype == "apk"')
        apk_block = source[apk_idx:apk_idx + 4000]
        assert "BasicPropertiesExtractor" in apk_block
        assert "HashExtractor" in apk_block


# ============================================================================
# APKExtractor base class
# ============================================================================

class TestAPKExtractorBase:

    def test_binary_property(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        # binary property should return the file content
        with open(apk_path, "rb") as f:
            expected = f.read()
        assert ext.binary == expected

    def test_is_valid_apk_with_apk(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        assert ext._is_valid_apk() is True

    def test_is_valid_apk_without_apk(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, _, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=None)
        ext.apk = None
        assert ext._is_valid_apk() is False

    def test_list_files(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        files = ext._list_files()
        assert len(files) == 5
        assert "classes.dex" in files

    def test_get_zip_file(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)
        zf = ext._get_zip_file()
        assert zf is not None
        zf.close()

    def test_sha256_computed_correctly(self, fake_apk_env):
        from redb.extractors.apk_extractors.apk_features import APKFeaturesExtractor

        apk_path, mock_apk, logger, exporters = fake_apk_env
        ext = APKFeaturesExtractor(apk_path, logger, exporters=exporters, apk=mock_apk)

        # Verify sha256 matches actual file content
        with open(apk_path, "rb") as f:
            expected_sha256 = hashlib.sha256(f.read()).hexdigest()
        assert ext.sha256 == expected_sha256