test_archan.py
1 """Main test module.""" 2 3 from typing import TYPE_CHECKING 4 5 from archan.dsm import DesignStructureMatrix as DSM # noqa: N817 6 from archan.plugins.checkers import ( 7 Checker, 8 CompleteMediation, 9 EconomyOfMechanism, 10 LayeredArchitecture, 11 LeastCommonMechanism, 12 LeastPrivileges, 13 SeparationOfPrivileges, 14 ) 15 16 if TYPE_CHECKING: 17 from archan.analysis import Result 18 19 20 class TestCheckers: 21 """Main test class. 22 23 It sets up two fake "webapp" and "genida" DSMs to check them. 24 """ 25 26 web_app_dsm: DSM 27 genida_dsm: DSM 28 29 @classmethod 30 def setup_class(cls) -> None: 31 """Setup function.""" 32 web_app_categories = [ 33 "appmodule", 34 "appmodule", 35 "appmodule", 36 "appmodule", 37 "broker", 38 "applib", 39 "data", 40 "data", 41 "data", 42 "framework", 43 "framework", 44 ] 45 46 web_app_entities = [ 47 "store", 48 "personal_information", 49 "order", 50 "payment", 51 "available_services", 52 "store_lib", 53 "store_data", 54 "client_data", 55 "order_data", 56 "framework", 57 "login", 58 ] 59 60 web_app_dependency_matrix = [ 61 [1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0], 62 [0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0], 63 [0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0], 64 [0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0], 65 [1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0], # broker 66 [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0], 67 [0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0], 68 [0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], 69 [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0], 70 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], 71 [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], 72 ] 73 74 cls.web_app_dsm = DSM(web_app_dependency_matrix, web_app_entities, web_app_categories) # type: ignore[arg-type] 75 76 genida_categories = [ 77 "framework", 78 "corelib", 79 "corelib", 80 "corelib", 81 "corelib", 82 "corelib", 83 "corelib", 84 "corelib", 85 "corelib", 86 "corelib", 87 "corelib", 88 "corelib", 89 "corelib", 90 "corelib", 91 "corelib", 92 "applib", 93 "applib", 94 "appmodule", 95 "applib", 96 "applib", 97 "applib", 98 "appmodule", 99 "appmodule", 100 "appmodule", 101 "appmodule", 102 "appmodule", 103 "broker", 104 ] 105 106 genida_entities = [ 107 "django", 108 "axes", 109 "modeltranslation", 110 "suit", 111 "markdown_deux", 112 "cities_light", 113 "avatar", 114 "djangobower", 115 "rosetta", 116 "imagekit", 117 "smart_selects", 118 "captcha", 119 "datetimewidget", 120 "django_forms_bootstrap", 121 "pagedown", 122 "dataforms", 123 "graph", 124 "news", 125 "cs_models", 126 "zxcvbn_password", 127 "dependenpy", 128 "complex", 129 "questionnaires", 130 "members", 131 "genida", 132 "security", 133 "services", 134 ] 135 136 genida_dependency_matrix = [ 137 [4438, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 138 [30, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 139 [50, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 140 [41, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 141 [3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 142 [43, 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 143 [32, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 144 [12, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 145 [36, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 146 [33, 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 147 [12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 148 [31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 149 [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 150 [3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 151 [11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 152 [75, 0, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 153 [7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0], 154 [12, 0, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 0, 0, 13, 0, 0, 0, 0, 0, 0, 0, 0, 1], 155 [5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 156 [7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0], 157 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 158 [13, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 7, 0, 0, 0, 0, 1], 159 [8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 160 [22, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 161 [26, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1], 162 [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 163 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1], 164 ] 165 166 cls.genida_dsm = DSM(genida_dependency_matrix, genida_entities, genida_categories) # type: ignore[arg-type] 167 168 # Webapp tests 169 def test_webapp_complete_mediation(self) -> None: 170 """Test complete mediation for webapp.""" 171 check = CompleteMediation() 172 check.run(self.web_app_dsm) 173 result: Result = check.result # type: ignore[assignment] 174 assert result.code == Checker.Code.PASSED, f"Complete mediation: {result.messages}" 175 176 def test_webapp_economy_of_mechanism(self) -> None: 177 """Test economoy of mechanism for webapp.""" 178 check = EconomyOfMechanism() 179 check.run(self.web_app_dsm) 180 result: Result = check.result # type: ignore[assignment] 181 assert result.code == Checker.Code.PASSED, f"Economy of mechanism: {result.messages}" 182 183 def test_webapp_least_common_mechanism(self) -> None: 184 """Test least common mechanism for webapp.""" 185 check = LeastCommonMechanism() 186 check.run(self.web_app_dsm) 187 result: Result = check.result # type: ignore[assignment] 188 assert result.code == Checker.Code.PASSED, f"Least common mechanism: {result.messages}" 189 190 # def test_webapp_code_clean(self) -> None: 191 # """Test code clean for webapp.""" 192 # result: Result = CodeClean().run(self.web_app_dsm) 193 # assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Code clean: {result.messages}" 194 195 def test_webapp_layered_architecture(self) -> None: 196 """Test layered architecture for webapp.""" 197 check = LayeredArchitecture() 198 check.run(self.web_app_dsm) 199 result: Result = check.result # type: ignore[assignment] 200 assert result.code == Checker.Code.FAILED, f"Layered architecture: {result.messages}" 201 202 def test_webapp_least_privileges(self) -> None: 203 """Test least privileges for webapp.""" 204 check = LeastPrivileges() 205 check.run(self.web_app_dsm) 206 result: Result = check.result # type: ignore[assignment] 207 assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Least privileges: {result.messages}" 208 209 def test_webapp_separation_of_privileges(self) -> None: 210 """Test separation of privileges for webapp.""" 211 check = SeparationOfPrivileges() 212 check.run(self.web_app_dsm) 213 result: Result = check.result # type: ignore[assignment] 214 assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Separation of privileges: {result.messages}" 215 216 # Genida tests 217 def test_genida_complete_mediation(self) -> None: 218 """Test complete mediation for webapp.""" 219 check = CompleteMediation() 220 check.run(self.genida_dsm) 221 result: Result = check.result # type: ignore[assignment] 222 assert result.code == Checker.Code.PASSED, f"Complete mediation: {result.messages}" 223 224 def test_genida_economy_of_mechanism(self) -> None: 225 """Test economoy of mechanism for webapp.""" 226 check = EconomyOfMechanism() 227 check.run(self.genida_dsm) 228 result: Result = check.result # type: ignore[assignment] 229 assert result.code == Checker.Code.PASSED, f"Economy of mechanism: {result.messages}" 230 231 def test_genida_least_common_mechanism(self) -> None: 232 """Test least common mechanism for webapp.""" 233 check = LeastCommonMechanism() 234 check.run(self.genida_dsm) 235 result: Result = check.result # type: ignore[assignment] 236 assert result.code == Checker.Code.PASSED, f"Least common mechanism: {result.messages}" 237 238 # def test_genida_code_clean(self) -> None: 239 # """Test code clean for webapp.""" 240 # result: Result = CodeClean().run(self.genida_dsm) 241 # assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Code clean: {result.messages}" 242 243 def test_genida_layered_architecture(self) -> None: 244 """Test layered architecture for webapp.""" 245 check = LayeredArchitecture(allow_failure=True) 246 check.run(self.genida_dsm) 247 result: Result = check.result # type: ignore[assignment] 248 assert result.code == Checker.Code.IGNORED, f"Layered architecture: {result.messages}" 249 250 def test_genida_least_privileges(self) -> None: 251 """Test least privileges for webapp.""" 252 check = LeastPrivileges(allow_failure=True) 253 check.run(self.genida_dsm) 254 result: Result = check.result # type: ignore[assignment] 255 assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Least privileges: {result.messages}" 256 257 def test_genida_separation_of_privileges(self) -> None: 258 """Test separation of privileges for webapp.""" 259 check = SeparationOfPrivileges() 260 check.run(self.genida_dsm) 261 result: Result = check.result # type: ignore[assignment] 262 assert result.code == Checker.Code.NOT_IMPLEMENTED, f"Separation of privileges: {result.messages}"