diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2025-12-01 22:25:39 +0000 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2025-12-01 22:25:39 +0000 |
| commit | 504eaf4f5aba93a3e935bbee76042dd35cada666 (patch) | |
| tree | e079d5002c08d655a3c686f1458b8d1e60c4e0b3 /grasp-audit/src | |
| parent | 11870a0f810accf0431d82a74b6fd3adec9d23df (diff) | |
better fixtures: test_head_set_after_state_event_with_existing_commit
Diffstat (limited to 'grasp-audit/src')
| -rw-r--r-- | grasp-audit/src/fixtures.rs | 89 | ||||
| -rw-r--r-- | grasp-audit/src/specs/grasp01/push_authorization.rs | 251 |
2 files changed, 117 insertions, 223 deletions
diff --git a/grasp-audit/src/fixtures.rs b/grasp-audit/src/fixtures.rs index d054e36..bda7a78 100644 --- a/grasp-audit/src/fixtures.rs +++ b/grasp-audit/src/fixtures.rs | |||
| @@ -200,6 +200,26 @@ pub enum FixtureKind { | |||
| 200 | /// - NOT sent to relay (use `client.send_event()` to publish when ready) | 200 | /// - NOT sent to relay (use `client.send_event()` to publish when ready) |
| 201 | PREventGenerated, | 201 | PREventGenerated, |
| 202 | 202 | ||
| 203 | /// HEAD set to 'develop' branch via state event | ||
| 204 | /// | ||
| 205 | /// This fixture tests that HEAD is updated when a state event is published | ||
| 206 | /// with HEAD pointing to a different branch that already has git data pushed. | ||
| 207 | /// | ||
| 208 | /// GRASP-01: "MUST set repository HEAD per repository state announcement | ||
| 209 | /// as soon as the git data related to that branch has been received." | ||
| 210 | /// | ||
| 211 | /// Stages: | ||
| 212 | /// 1. **Depends on**: RecursiveMaintainerStateDataPushed (all git data exists on main) | ||
| 213 | /// 2. **Creates**: New state event with HEAD=refs/heads/develop pointing to existing commit | ||
| 214 | /// 3. **Sends**: State event to relay | ||
| 215 | /// 4. **Verifies**: Can be checked via get_default_branch_from_info_refs | ||
| 216 | /// | ||
| 217 | /// - Requires RecursiveMaintainerStateDataPushed (establishes full maintainer chain with git data) | ||
| 218 | /// - Creates state event signed by maintainer keys (`client.maintainer_keys()`) | ||
| 219 | /// - Points refs/heads/develop to RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH | ||
| 220 | /// - Sets HEAD to refs/heads/develop | ||
| 221 | HeadSetToDevelopBranch, | ||
| 222 | |||
| 203 | /// Wrong commit pushed to refs/nostr/<pr-event-id> BEFORE PR event is sent | 223 | /// Wrong commit pushed to refs/nostr/<pr-event-id> BEFORE PR event is sent |
| 204 | /// | 224 | /// |
| 205 | /// This is a "DataPushed" stage fixture for testing pre-event ref behavior. | 225 | /// This is a "DataPushed" stage fixture for testing pre-event ref behavior. |
| @@ -327,6 +347,10 @@ impl FixtureKind { | |||
| 327 | // RecursiveMaintainerStateDataPushed depends on MaintainerStateDataPushed | 347 | // RecursiveMaintainerStateDataPushed depends on MaintainerStateDataPushed |
| 328 | // (recursive maintainer force-pushes over maintainer's data) | 348 | // (recursive maintainer force-pushes over maintainer's data) |
| 329 | Self::RecursiveMaintainerStateDataPushed => vec![Self::MaintainerStateDataPushed], | 349 | Self::RecursiveMaintainerStateDataPushed => vec![Self::MaintainerStateDataPushed], |
| 350 | |||
| 351 | // HeadSetToDevelopBranch depends on RecursiveMaintainerStateDataPushed | ||
| 352 | // (all git data already exists, we just publish a new state event) | ||
| 353 | Self::HeadSetToDevelopBranch => vec![Self::RecursiveMaintainerStateDataPushed], | ||
| 330 | } | 354 | } |
| 331 | } | 355 | } |
| 332 | 356 | ||
| @@ -349,6 +373,8 @@ impl FixtureKind { | |||
| 349 | Self::PRWrongCommitPushedBeforeEvent => true, | 373 | Self::PRWrongCommitPushedBeforeEvent => true, |
| 350 | // PREventSentAfterWrongPush sends the PR event internally | 374 | // PREventSentAfterWrongPush sends the PR event internally |
| 351 | Self::PREventSentAfterWrongPush => true, | 375 | Self::PREventSentAfterWrongPush => true, |
| 376 | // HeadSetToDevelopBranch sends its state event internally | ||
| 377 | Self::HeadSetToDevelopBranch => true, | ||
| 352 | // All other fixtures return a single event for the caller to send | 378 | // All other fixtures return a single event for the caller to send |
| 353 | _ => false, | 379 | _ => false, |
| 354 | } | 380 | } |
| @@ -868,6 +894,10 @@ impl<'a> TestContext<'a> { | |||
| 868 | FixtureKind::RecursiveMaintainerStateDataPushed => { | 894 | FixtureKind::RecursiveMaintainerStateDataPushed => { |
| 869 | self.build_recursive_maintainer_state_data_pushed().await | 895 | self.build_recursive_maintainer_state_data_pushed().await |
| 870 | } | 896 | } |
| 897 | |||
| 898 | FixtureKind::HeadSetToDevelopBranch => { | ||
| 899 | self.build_head_set_to_develop_branch().await | ||
| 900 | } | ||
| 871 | } | 901 | } |
| 872 | } | 902 | } |
| 873 | 903 | ||
| @@ -1474,6 +1504,65 @@ impl<'a> TestContext<'a> { | |||
| 1474 | } | 1504 | } |
| 1475 | } | 1505 | } |
| 1476 | 1506 | ||
| 1507 | /// Build HeadSetToDevelopBranch fixture: creates state event with HEAD=develop | ||
| 1508 | /// | ||
| 1509 | /// This tests that HEAD is updated when a state event is published with HEAD | ||
| 1510 | /// pointing to a different branch that already has git data pushed. | ||
| 1511 | /// | ||
| 1512 | /// GRASP-01: "MUST set repository HEAD per repository state announcement | ||
| 1513 | /// as soon as the git data related to that branch has been received." | ||
| 1514 | /// | ||
| 1515 | /// Depends on RecursiveMaintainerStateDataPushed - all git data already exists. | ||
| 1516 | /// We just create a new state event with HEAD=refs/heads/develop pointing to | ||
| 1517 | /// the already-pushed commit. | ||
| 1518 | /// | ||
| 1519 | /// # Returns | ||
| 1520 | /// The state event (kind 30618) with HEAD=refs/heads/develop after it's sent | ||
| 1521 | async fn build_head_set_to_develop_branch(&self) -> Result<Event> { | ||
| 1522 | use nostr_sdk::prelude::*; | ||
| 1523 | |||
| 1524 | // ============================================================ | ||
| 1525 | // Stage 1: RecursiveMaintainerStateDataPushed is ensured by ensure_fixture before this is called | ||
| 1526 | // All git data already exists on the relay (main branch with RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH) | ||
| 1527 | // ============================================================ | ||
| 1528 | let recursive_state = self.get_cached_dependency(FixtureKind::RecursiveMaintainerStateDataPushed)?; | ||
| 1529 | |||
| 1530 | // Extract repo_id from the recursive maintainer's state event | ||
| 1531 | let repo_id = self.extract_repo_id(&recursive_state)?; | ||
| 1532 | |||
| 1533 | // ============================================================ | ||
| 1534 | // Stage 2: Create state event with HEAD=refs/heads/develop | ||
| 1535 | // ============================================================ | ||
| 1536 | // Use the same commit hash that's already pushed to the relay | ||
| 1537 | // but point HEAD to develop branch instead of main | ||
| 1538 | let base_time = Timestamp::now().as_u64(); | ||
| 1539 | let develop_timestamp = Timestamp::from(base_time - 1); // 1 second ago (most recent) | ||
| 1540 | |||
| 1541 | let develop_state_event = self | ||
| 1542 | .client | ||
| 1543 | .event_builder(Kind::Custom(30618), "") | ||
| 1544 | .tag(Tag::identifier(&repo_id)) | ||
| 1545 | .tag(Tag::custom( | ||
| 1546 | TagKind::custom("HEAD"), | ||
| 1547 | vec!["refs/heads/develop".to_string()], | ||
| 1548 | )) | ||
| 1549 | .tag(Tag::custom( | ||
| 1550 | TagKind::custom("refs/heads/develop"), | ||
| 1551 | vec![RECURSIVE_MAINTAINER_DETERMINISTIC_COMMIT_HASH.to_string()], | ||
| 1552 | )) | ||
| 1553 | .custom_time(develop_timestamp) | ||
| 1554 | .build(self.client.maintainer_keys()) | ||
| 1555 | .map_err(|e| anyhow::anyhow!("Failed to build develop state event: {}", e))?; | ||
| 1556 | |||
| 1557 | // Send state event to relay | ||
| 1558 | self.client.send_event(develop_state_event.clone()).await?; | ||
| 1559 | |||
| 1560 | // Wait for relay to process the state event | ||
| 1561 | tokio::time::sleep(std::time::Duration::from_millis(500)).await; | ||
| 1562 | |||
| 1563 | Ok(develop_state_event) | ||
| 1564 | } | ||
| 1565 | |||
| 1477 | /// Build PRWrongCommitPushedBeforeEvent fixture | 1566 | /// Build PRWrongCommitPushedBeforeEvent fixture |
| 1478 | /// | 1567 | /// |
| 1479 | /// This fixture sets up a scenario where: | 1568 | /// This fixture sets up a scenario where: |
diff --git a/grasp-audit/src/specs/grasp01/push_authorization.rs b/grasp-audit/src/specs/grasp01/push_authorization.rs index 0119ab3..9e8597b 100644 --- a/grasp-audit/src/specs/grasp01/push_authorization.rs +++ b/grasp-audit/src/specs/grasp01/push_authorization.rs | |||
| @@ -34,7 +34,6 @@ const PR_TEST_COMMIT_HASH: &str = "5d40fb1555a0c28bf4d650515a73aaa54d4d9bfb"; | |||
| 34 | use crate::{ | 34 | use crate::{ |
| 35 | clone_repo, create_commit, create_deterministic_commit_with_variant, try_push, try_push_to_ref, | 35 | clone_repo, create_commit, create_deterministic_commit_with_variant, try_push, try_push_to_ref, |
| 36 | AuditClient, CommitVariant, FixtureKind, TestContext, TestResult, | 36 | AuditClient, CommitVariant, FixtureKind, TestContext, TestResult, |
| 37 | MAINTAINER_DETERMINISTIC_COMMIT_HASH, | ||
| 38 | }; | 37 | }; |
| 39 | use nostr_sdk::prelude::*; | 38 | use nostr_sdk::prelude::*; |
| 40 | use std::fs; | 39 | use std::fs; |
| @@ -1292,41 +1291,50 @@ impl PushAuthorizationTests { | |||
| 1292 | /// as soon as the git data related to that branch has been received." | 1291 | /// as soon as the git data related to that branch has been received." |
| 1293 | /// | 1292 | /// |
| 1294 | /// This test verifies the HEAD-setting behavior when: | 1293 | /// This test verifies the HEAD-setting behavior when: |
| 1295 | /// 1. A maintainer commit is pushed to the relay (git data exists) | 1294 | /// 1. Git data has already been pushed via RecursiveMaintainerStateDataPushed |
| 1296 | /// 2. A state event is published pointing to that commit with HEAD="refs/heads/develop" | 1295 | /// 2. A new state event is published with HEAD="refs/heads/develop" |
| 1297 | /// 3. The relay should update the repository's default branch to "develop" | 1296 | /// 3. The relay should update the repository's default branch to "develop" |
| 1298 | /// | 1297 | /// |
| 1299 | /// ## Fixture-First Pattern | 1298 | /// ## Fixture-First Pattern |
| 1300 | /// | 1299 | /// |
| 1301 | /// 1. **Generate**: Create TestContext and get RepoState + MaintainerState fixtures | 1300 | /// Uses HeadSetToDevelopBranch fixture which: |
| 1302 | /// (both commits are pushed as part of the fixture setup) | 1301 | /// 1. **Depends on**: RecursiveMaintainerStateDataPushed (all git data exists) |
| 1303 | /// 2. **Send**: Push maintainer commit to relay first, then publish state event with HEAD=develop | 1302 | /// 2. **Creates**: New state event with HEAD=refs/heads/develop |
| 1304 | /// 3. **Verify**: Query info/refs to verify HEAD symref points to refs/heads/develop | 1303 | /// 3. **Sends**: State event to relay |
| 1304 | /// 4. **Verify**: Query info/refs to verify HEAD symref points to refs/heads/develop | ||
| 1305 | pub async fn test_head_set_after_state_event_with_existing_commit( | 1305 | pub async fn test_head_set_after_state_event_with_existing_commit( |
| 1306 | client: &AuditClient, | 1306 | client: &AuditClient, |
| 1307 | relay_domain: &str, | 1307 | relay_domain: &str, |
| 1308 | ) -> TestResult { | 1308 | ) -> TestResult { |
| 1309 | use std::process::Command; | ||
| 1310 | |||
| 1311 | let test_name = "test_head_set_after_state_event_with_existing_commit"; | 1309 | let test_name = "test_head_set_after_state_event_with_existing_commit"; |
| 1312 | let desc = "HEAD is set when state event published with existing commit"; | 1310 | let desc = "HEAD is set when state event published with existing commit"; |
| 1313 | 1311 | ||
| 1314 | // ============================================================ | 1312 | // ============================================================ |
| 1315 | // Step 1: GENERATE - Create TestContext and get fixtures | 1313 | // Step 1: Get HeadSetToDevelopBranch fixture |
| 1314 | // This sets up everything: repo, maintainer chain, git data, and state event with HEAD=develop | ||
| 1316 | // ============================================================ | 1315 | // ============================================================ |
| 1317 | let ctx = TestContext::new(client); | 1316 | let ctx = TestContext::new(client); |
| 1318 | 1317 | ||
| 1319 | // Get RepoState fixture (owner's repo announcement + state event) | 1318 | let _develop_state_event = match ctx.get_fixture(FixtureKind::HeadSetToDevelopBranch).await { |
| 1320 | let state_event = match ctx.get_fixture(FixtureKind::RepoState).await { | ||
| 1321 | Ok(e) => e, | 1319 | Ok(e) => e, |
| 1322 | Err(e) => { | 1320 | Err(e) => { |
| 1323 | return TestResult::new(test_name, "GRASP-01", desc) | 1321 | return TestResult::new(test_name, "GRASP-01", desc) |
| 1324 | .fail(format!("Failed to create RepoState fixture: {}", e)); | 1322 | .fail(format!("Failed to create HeadSetToDevelopBranch fixture: {}", e)); |
| 1325 | } | 1323 | } |
| 1326 | }; | 1324 | }; |
| 1327 | 1325 | ||
| 1328 | // Extract repo_id and npub from owner's state event | 1326 | // ============================================================ |
| 1329 | let repo_id = match state_event | 1327 | // Step 2: Extract repo_id and owner npub from ValidRepo (cached by fixture) |
| 1328 | // ============================================================ | ||
| 1329 | let valid_repo = match ctx.get_fixture(FixtureKind::ValidRepo).await { | ||
| 1330 | Ok(e) => e, | ||
| 1331 | Err(e) => { | ||
| 1332 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1333 | .fail(format!("Failed to get ValidRepo fixture: {}", e)); | ||
| 1334 | } | ||
| 1335 | }; | ||
| 1336 | |||
| 1337 | let repo_id = match valid_repo | ||
| 1330 | .tags | 1338 | .tags |
| 1331 | .iter() | 1339 | .iter() |
| 1332 | .find(|t| t.kind() == TagKind::d()) | 1340 | .find(|t| t.kind() == TagKind::d()) |
| @@ -1335,11 +1343,11 @@ impl PushAuthorizationTests { | |||
| 1335 | Some(id) => id.to_string(), | 1343 | Some(id) => id.to_string(), |
| 1336 | None => { | 1344 | None => { |
| 1337 | return TestResult::new(test_name, "GRASP-01", desc) | 1345 | return TestResult::new(test_name, "GRASP-01", desc) |
| 1338 | .fail("Missing repo_id in state event"); | 1346 | .fail("Missing repo_id in ValidRepo"); |
| 1339 | } | 1347 | } |
| 1340 | }; | 1348 | }; |
| 1341 | 1349 | ||
| 1342 | let npub = match state_event.pubkey.to_bech32() { | 1350 | let npub = match valid_repo.pubkey.to_bech32() { |
| 1343 | Ok(n) => n, | 1351 | Ok(n) => n, |
| 1344 | Err(e) => { | 1352 | Err(e) => { |
| 1345 | return TestResult::new(test_name, "GRASP-01", desc) | 1353 | return TestResult::new(test_name, "GRASP-01", desc) |
| @@ -1347,211 +1355,8 @@ impl PushAuthorizationTests { | |||
| 1347 | } | 1355 | } |
| 1348 | }; | 1356 | }; |
| 1349 | 1357 | ||
| 1350 | let _maintainer_ann_event = match ctx.get_fixture(FixtureKind::MaintainerAnnouncement).await | ||
| 1351 | { | ||
| 1352 | Ok(e) => e, | ||
| 1353 | Err(e) => { | ||
| 1354 | return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1355 | "Failed to create MaintainerAnnouncement fixture: {}", | ||
| 1356 | e | ||
| 1357 | )); | ||
| 1358 | } | ||
| 1359 | }; | ||
| 1360 | |||
| 1361 | let _maintainer_state_event = match ctx.get_fixture(FixtureKind::MaintainerState).await { | ||
| 1362 | Ok(e) => e, | ||
| 1363 | Err(e) => { | ||
| 1364 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1365 | .fail(format!("Failed to create MaintainerState fixture: {}", e)); | ||
| 1366 | } | ||
| 1367 | }; | ||
| 1368 | |||
| 1369 | tokio::time::sleep(std::time::Duration::from_millis(200)).await; | ||
| 1370 | |||
| 1371 | // ============================================================ | 1358 | // ============================================================ |
| 1372 | // Step 2: SEND - First push maintainer commit so relay has the git data | 1359 | // Step 3: VERIFY - Query info/refs to check the default branch |
| 1373 | // ============================================================ | ||
| 1374 | let clone_path = match clone_repo(relay_domain, &npub, &repo_id) { | ||
| 1375 | Ok(p) => p, | ||
| 1376 | Err(e) => { | ||
| 1377 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1378 | .fail(format!("Failed to clone repo: {}", e)); | ||
| 1379 | } | ||
| 1380 | }; | ||
| 1381 | |||
| 1382 | let cleanup = || { | ||
| 1383 | let _ = fs::remove_dir_all(&clone_path); | ||
| 1384 | }; | ||
| 1385 | |||
| 1386 | // TODO - this should be pushed inside the MaintainerState fixture. | ||
| 1387 | |||
| 1388 | // Reset to orphan state and create deterministic root commit | ||
| 1389 | // Step 1: Create orphan branch (removes all history) | ||
| 1390 | let _ = Command::new("git") | ||
| 1391 | .args(["checkout", "--orphan", "main"]) | ||
| 1392 | .current_dir(&clone_path) | ||
| 1393 | .output(); | ||
| 1394 | |||
| 1395 | // Step 2: Clear staged files (orphan keeps files staged from previous branch) | ||
| 1396 | let _ = Command::new("git") | ||
| 1397 | .args(["rm", "-rf", "--cached", "."]) | ||
| 1398 | .current_dir(&clone_path) | ||
| 1399 | .output(); | ||
| 1400 | |||
| 1401 | // Step 3: Create deterministic commit using Maintainer variant | ||
| 1402 | let commit_hash = match create_deterministic_commit_with_variant( | ||
| 1403 | &clone_path, | ||
| 1404 | CommitVariant::Maintainer, | ||
| 1405 | ) { | ||
| 1406 | Ok(h) => h, | ||
| 1407 | Err(e) => { | ||
| 1408 | cleanup(); | ||
| 1409 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1410 | .fail(format!("Failed to create maintainer commit: {}", e)); | ||
| 1411 | } | ||
| 1412 | }; | ||
| 1413 | |||
| 1414 | // Verify commit hash matches expected | ||
| 1415 | if commit_hash != MAINTAINER_DETERMINISTIC_COMMIT_HASH { | ||
| 1416 | cleanup(); | ||
| 1417 | return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1418 | "Maintainer commit hash mismatch: got {}, expected {}", | ||
| 1419 | commit_hash, MAINTAINER_DETERMINISTIC_COMMIT_HASH | ||
| 1420 | )); | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | // Push the develop branch with the maintainer commit | ||
| 1424 | let push_output = Command::new("git") | ||
| 1425 | .args(["push", "origin", "main"]) | ||
| 1426 | .current_dir(&clone_path) | ||
| 1427 | .env("GIT_TERMINAL_PROMPT", "0") | ||
| 1428 | .output(); | ||
| 1429 | |||
| 1430 | match push_output { | ||
| 1431 | Err(e) => { | ||
| 1432 | cleanup(); | ||
| 1433 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1434 | .fail(format!("Failed to push develop branch: {}", e)); | ||
| 1435 | } | ||
| 1436 | Ok(output) if !output.status.success() => { | ||
| 1437 | // this will fail when not in isolation - as the Recusive state will be the authorised state | ||
| 1438 | // but we need to do it here so the grasp server has the oid | ||
| 1439 | } | ||
| 1440 | _ => {} | ||
| 1441 | } | ||
| 1442 | |||
| 1443 | let _recursive_maintainer_ann_event = match ctx | ||
| 1444 | .get_fixture(FixtureKind::RecursiveMaintainerAnnouncement) | ||
| 1445 | .await | ||
| 1446 | { | ||
| 1447 | Ok(e) => e, | ||
| 1448 | Err(e) => { | ||
| 1449 | return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1450 | "Failed to create RecursiveMaintainerAnnouncement fixture: {}", | ||
| 1451 | e | ||
| 1452 | )); | ||
| 1453 | } | ||
| 1454 | }; | ||
| 1455 | |||
| 1456 | let _recursive_maintainer_state_event = | ||
| 1457 | match ctx.get_fixture(FixtureKind::RecursiveMaintainerState).await { | ||
| 1458 | Ok(e) => e, | ||
| 1459 | Err(e) => { | ||
| 1460 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1461 | .fail(format!("Failed to create MaintainerState fixture: {}", e)); | ||
| 1462 | } | ||
| 1463 | }; | ||
| 1464 | |||
| 1465 | // Verify commit hash matches expected | ||
| 1466 | if commit_hash != MAINTAINER_DETERMINISTIC_COMMIT_HASH { | ||
| 1467 | cleanup(); | ||
| 1468 | return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1469 | "Maintainer commit hash mismatch: got {}, expected {}", | ||
| 1470 | commit_hash, MAINTAINER_DETERMINISTIC_COMMIT_HASH | ||
| 1471 | )); | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | // Reset to orphan state and create deterministic root commit | ||
| 1475 | // Step 1: Create orphan branch (removes all history) | ||
| 1476 | let _ = Command::new("git") | ||
| 1477 | .args(["checkout", "--orphan", "develop"]) | ||
| 1478 | .current_dir(&clone_path) | ||
| 1479 | .output(); | ||
| 1480 | |||
| 1481 | // Step 2: Clear staged files (orphan keeps files staged from previous branch) | ||
| 1482 | let _ = Command::new("git") | ||
| 1483 | .args(["rm", "-rf", "--cached", "."]) | ||
| 1484 | .current_dir(&clone_path) | ||
| 1485 | .output(); | ||
| 1486 | |||
| 1487 | // ============================================================ | ||
| 1488 | // Step 3: Publish state event with HEAD pointing to develop branch | ||
| 1489 | // ============================================================ | ||
| 1490 | |||
| 1491 | // Create state event with HEAD=refs/heads/develop and develop branch pointing to maintainer commit | ||
| 1492 | let state_event = match client | ||
| 1493 | .event_builder(Kind::Custom(30618), "") | ||
| 1494 | .tag(Tag::identifier(&repo_id)) | ||
| 1495 | .tag(Tag::custom( | ||
| 1496 | TagKind::custom("HEAD"), | ||
| 1497 | vec!["refs/heads/develop".to_string()], | ||
| 1498 | )) | ||
| 1499 | .tag(Tag::custom( | ||
| 1500 | TagKind::custom("refs/heads/develop"), | ||
| 1501 | vec![MAINTAINER_DETERMINISTIC_COMMIT_HASH.to_string()], | ||
| 1502 | )) | ||
| 1503 | .build(client.maintainer_keys()) | ||
| 1504 | { | ||
| 1505 | Ok(e) => e, | ||
| 1506 | Err(e) => { | ||
| 1507 | cleanup(); | ||
| 1508 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1509 | .fail(format!("Failed to build state event: {}", e)); | ||
| 1510 | } | ||
| 1511 | }; | ||
| 1512 | |||
| 1513 | // Send the state event | ||
| 1514 | if let Err(e) = client.client().send_event(&state_event).await { | ||
| 1515 | cleanup(); | ||
| 1516 | return TestResult::new(test_name, "GRASP-01", desc) | ||
| 1517 | .fail(format!("Failed to send state event: {}", e)); | ||
| 1518 | } | ||
| 1519 | |||
| 1520 | // Wait for relay to process the state event | ||
| 1521 | tokio::time::sleep(std::time::Duration::from_millis(500)).await; | ||
| 1522 | |||
| 1523 | // // Now that state event is published, try pushing again if previous push failed | ||
| 1524 | // let push_output = Command::new("git") | ||
| 1525 | // .args(["push", "-f", "origin", "develop"]) | ||
| 1526 | // .current_dir(&clone_path) | ||
| 1527 | // .env("GIT_TERMINAL_PROMPT", "0") | ||
| 1528 | // .output(); | ||
| 1529 | |||
| 1530 | // match push_output { | ||
| 1531 | // Err(e) => { | ||
| 1532 | // cleanup(); | ||
| 1533 | // return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1534 | // "Failed to push develop branch after state event: {}", | ||
| 1535 | // e | ||
| 1536 | // )); | ||
| 1537 | // } | ||
| 1538 | // Ok(output) if !output.status.success() => { | ||
| 1539 | // cleanup(); | ||
| 1540 | // return TestResult::new(test_name, "GRASP-01", desc).fail(format!( | ||
| 1541 | // "Push of develop branch rejected after state event: {}", | ||
| 1542 | // String::from_utf8_lossy(&output.stderr) | ||
| 1543 | // )); | ||
| 1544 | // } | ||
| 1545 | // _ => {} | ||
| 1546 | // } | ||
| 1547 | |||
| 1548 | cleanup(); | ||
| 1549 | |||
| 1550 | // Wait a bit more for HEAD to be updated | ||
| 1551 | tokio::time::sleep(std::time::Duration::from_millis(300)).await; | ||
| 1552 | |||
| 1553 | // ============================================================ | ||
| 1554 | // Step 4: VERIFY - Query info/refs to check the default branch | ||
| 1555 | // ============================================================ | 1360 | // ============================================================ |
| 1556 | let default_branch = | 1361 | let default_branch = |
| 1557 | match get_default_branch_from_info_refs(relay_domain, &npub, &repo_id).await { | 1362 | match get_default_branch_from_info_refs(relay_domain, &npub, &repo_id).await { |
| @@ -1577,8 +1382,8 @@ impl PushAuthorizationTests { | |||
| 1577 | 1382 | ||
| 1578 | /// Test that HEAD is set after git push with oids | 1383 | /// Test that HEAD is set after git push with oids |
| 1579 | pub async fn test_head_set_after_git_push_with_required_oids( | 1384 | pub async fn test_head_set_after_git_push_with_required_oids( |
| 1580 | client: &AuditClient, | 1385 | _client: &AuditClient, |
| 1581 | relay_domain: &str, | 1386 | _relay_domain: &str, |
| 1582 | ) -> TestResult { | 1387 | ) -> TestResult { |
| 1583 | let test_name = "test_head_set_after_git_push_with_required_oids"; | 1388 | let test_name = "test_head_set_after_git_push_with_required_oids"; |
| 1584 | let desc = "HEAD is set to match state event when git push sends required oids to formulate branch"; | 1389 | let desc = "HEAD is set to match state event when git push sends required oids to formulate branch"; |