@@ -84,3 +84,132 @@ def test_load_gcp_projects_without_parent(neo4j_session):
84
84
)
85
85
actual_nodes = {(n ["d.id" ]) for n in nodes }
86
86
assert actual_nodes == expected_nodes
87
+
88
+
89
+ def test_sync_gcp_organizations (neo4j_session ):
90
+ """
91
+ Test that sync_gcp_organizations correctly syncs GCP organizations to Neo4j.
92
+ """
93
+ common_job_parameters = {"UPDATE_TAG" : TEST_UPDATE_TAG }
94
+
95
+ # Load organizations
96
+ cartography .intel .gcp .crm .load_gcp_organizations (
97
+ neo4j_session ,
98
+ tests .data .gcp .crm .GCP_ORGANIZATIONS ,
99
+ TEST_UPDATE_TAG ,
100
+ )
101
+
102
+ # Verify organizations are loaded correctly
103
+ expected_nodes = {"organizations/1337" }
104
+ nodes = neo4j_session .run ("MATCH (o:GCPOrganization) RETURN o.id" )
105
+ actual_nodes = {n ["o.id" ] for n in nodes }
106
+ assert actual_nodes == expected_nodes
107
+
108
+ # Verify organization properties
109
+ org_query = """
110
+ MATCH (o:GCPOrganization{id: 'organizations/1337'})
111
+ RETURN o.displayname, o.lifecyclestate, o.lastupdated
112
+ """
113
+ result = neo4j_session .run (org_query ).single ()
114
+ assert result ["o.displayname" ] == "example.com"
115
+ assert result ["o.lifecyclestate" ] == "ACTIVE"
116
+ assert result ["o.lastupdated" ] == TEST_UPDATE_TAG
117
+
118
+
119
+ def test_sync_gcp_folders (neo4j_session ):
120
+ """
121
+ Test that sync_gcp_folders correctly syncs GCP folders to Neo4j.
122
+ """
123
+ # Load parent organization
124
+ cartography .intel .gcp .crm .load_gcp_organizations (
125
+ neo4j_session ,
126
+ tests .data .gcp .crm .GCP_ORGANIZATIONS ,
127
+ TEST_UPDATE_TAG ,
128
+ )
129
+
130
+ common_job_parameters = {"UPDATE_TAG" : TEST_UPDATE_TAG }
131
+
132
+ # Load folders
133
+ cartography .intel .gcp .crm .load_gcp_folders (
134
+ neo4j_session ,
135
+ tests .data .gcp .crm .GCP_FOLDERS ,
136
+ TEST_UPDATE_TAG ,
137
+ )
138
+
139
+ # Verify folders are loaded correctly
140
+ expected_nodes = {"folders/1414" }
141
+ nodes = neo4j_session .run ("MATCH (f:GCPFolder) RETURN f.id" )
142
+ actual_nodes = {n ["f.id" ] for n in nodes }
143
+ assert actual_nodes == expected_nodes
144
+
145
+ # Verify folder properties
146
+ folder_query = """
147
+ MATCH (f:GCPFolder{id: 'folders/1414'})
148
+ RETURN f.displayname, f.lifecyclestate, f.lastupdated
149
+ """
150
+ result = neo4j_session .run (folder_query ).single ()
151
+ assert result ["f.displayname" ] == "my-folder"
152
+ assert result ["f.lifecyclestate" ] == "ACTIVE"
153
+ assert result ["f.lastupdated" ] == TEST_UPDATE_TAG
154
+
155
+ # Verify relationship: Organization -> Folder
156
+ relationship_query = """
157
+ MATCH (o:GCPOrganization{id: 'organizations/1337'})-[:RESOURCE]->(f:GCPFolder{id: 'folders/1414'})
158
+ RETURN COUNT(*) as count
159
+ """
160
+ result = neo4j_session .run (relationship_query ).single ()
161
+ assert result ["count" ] == 1
162
+
163
+
164
+ def test_sync_gcp_projects (neo4j_session ):
165
+ """
166
+ Test that sync_gcp_projects correctly syncs GCP projects to Neo4j.
167
+ """
168
+ # Clear existing project nodes
169
+ neo4j_session .run ("MATCH (p:GCPProject) DETACH DELETE p" )
170
+
171
+ # Load referenced parent organization and folder
172
+ cartography .intel .gcp .crm .load_gcp_organizations (
173
+ neo4j_session ,
174
+ tests .data .gcp .crm .GCP_ORGANIZATIONS ,
175
+ TEST_UPDATE_TAG ,
176
+ )
177
+ cartography .intel .gcp .crm .load_gcp_folders (
178
+ neo4j_session ,
179
+ tests .data .gcp .crm .GCP_FOLDERS ,
180
+ TEST_UPDATE_TAG ,
181
+ )
182
+
183
+ common_job_parameters = {"UPDATE_TAG" : TEST_UPDATE_TAG }
184
+
185
+ # Run sync
186
+ cartography .intel .gcp .crm .sync_gcp_projects (
187
+ neo4j_session ,
188
+ tests .data .gcp .crm .GCP_PROJECTS ,
189
+ TEST_UPDATE_TAG ,
190
+ common_job_parameters ,
191
+ )
192
+
193
+ expected_nodes = {"this-project-has-a-parent-232323" }
194
+ nodes = neo4j_session .run ("MATCH (p:GCPProject) RETURN p.id" )
195
+ actual_nodes = {n ["p.id" ] for n in nodes }
196
+ assert actual_nodes == expected_nodes
197
+
198
+ # project properties
199
+ project_query = """
200
+ MATCH (p:GCPProject{id: 'this-project-has-a-parent-232323'})
201
+ RETURN p.projectnumber, p.displayname, p.lifecyclestate, p.lastupdated
202
+ """
203
+ result = neo4j_session .run (project_query ).single ()
204
+ assert result ["p.projectnumber" ] == "232323"
205
+ assert result ["p.displayname" ] == "Group 1"
206
+ assert result ["p.lifecyclestate" ] == "ACTIVE"
207
+ assert result ["p.lastupdated" ] == TEST_UPDATE_TAG
208
+
209
+ # Organization -> Folder -> Project
210
+ hierarchy_query = """
211
+ MATCH (o:GCPOrganization{id: 'organizations/1337'})-[:RESOURCE]->(f:GCPFolder{id: 'folders/1414'})-[:RESOURCE]->(p:GCPProject{id: 'this-project-has-a-parent-232323'})
212
+ RETURN COUNT(*) as count
213
+ """
214
+ result = neo4j_session .run (hierarchy_query ).single ()
215
+ assert result ["count" ] == 1
0 commit comments