code: def test_simple(self):
      tenant_col = "tenant"
      user_col = "user"
      res_col = "res"
      likelihood_col = "likelihood"
  
      df_schema = t.StructType(
          [
              t.StructField(tenant_col, t.StringType(), False),
              t.StructField(user_col, t.StringType(), False),
              t.StructField(res_col, t.StringType(), False),
              t.StructField(likelihood_col, t.DoubleType(), False),
          ],
      )
  
      df = spark.createDataFrame(
          [
              ["0", "user0", "res0", 4.0],
              ["0", "user1", "res0", 8.0],
              ["0", "user1", "res1", 7.0],
              ["0", "user2", "res1", 8.0],
              ["0", "user3", "res1", 8.0],
              ["0", "user3", "res2", 8.0],
              ["0", "user4", "res3", 10.0],
          ],
          df_schema,
      )
  
      cc = ConnectedComponents(tenant_col, user_col, res_col)
      user2components, res2components = cc.transform(df)
  
      user_components = [
          row["users"]
          for row in user2components.groupBy("component")
          .agg(f.collect_list("user").alias("users"))
          .orderBy("component")
          .select("users")
          .collect()
      ]
  
      assert len(user_components) == 2
      assert set(user_components[0]) == {
          "user0",
          "user1",
          "user2",
          "user3",
      }
      assert set(user_components[1]) == {"user4"}
  
      res_components = [
          row["resources"]
          for row in res2components.groupBy("component")
          .agg(f.collect_list("res").alias("resources"))
          .orderBy("component")
          .select("resources")
          .collect()
      ]
  
      assert len(res_components) == 2
      assert set(res_components[0]) == {"res0", "res1", "res2"}
      assert set(res_components[1]) == {"res3"}
  
imports: import os
  import tempfile
  import unittest
  from typing import Dict, Optional, Set, Type, Union
  from pandas.testing import assert_frame_equal
  from pyspark.sql import DataFrame, types, functions
  from synapse.ml.cyber.feature import indexers
  from synapse.ml.cyber import DataFactory
  from synapse.ml.cyber.anomaly.collaborative_filtering import AccessAnomaly, AccessAnomalyModel, AccessAnomalyConfig, ConnectedComponents, ModelNormalizeTransformer, _UserResourceFeatureVectorMapping
  from synapsemltest.cyber.explain_tester import ExplainTester
  from synapsemltest.spark import *
label_desc: Use image node_id 1 for calling the TestConnectedComponents obj's underlying member method code with example usage: obj.test_simple() without return types