/ tests / test_archan.py
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}"