This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / knot2 / crates / knot-cobs / tests / common / mod.rs
6.2 kB 213 lines
1#![allow(dead_code)] 2 3use knot_cob::{ChangePayload, CobError, CobHome, CobId, CobStore}; 4use knot_cobs::{Grant, Members, MembersChange, MembersCob, Registration, RegistryChange, Rename}; 5use knot_git::{Layout, RefUpdate, Repo}; 6use knot_runtime::{K256Signer, SeededEntropy, Signer}; 7use knot_types::{ 8 AccountDid, ActorId, Oid, OwnerDid, RefName, RepoDid, RepoName, RepoRkey, TypeName, UnixSeconds, 9}; 10use tempfile::TempDir; 11 12pub fn fixture() -> (TempDir, Repo) { 13 let dir = tempfile::tempdir().unwrap(); 14 let repo = Layout::new(dir.path()) 15 .create(&RepoDid::new("did:plc:squid").unwrap()) 16 .unwrap(); 17 (dir, repo) 18} 19 20pub fn signer(seed: u64) -> K256Signer { 21 K256Signer::generate(&SeededEntropy::new(seed)) 22} 23 24pub fn home() -> CobHome { 25 CobHome::from(&RepoDid::new("did:plc:squid").unwrap()) 26} 27 28pub fn account(suffix: &str) -> AccountDid { 29 AccountDid::new(format!("did:plc:{suffix}")).unwrap() 30} 31 32pub fn grant(subject: &str, added_by: &str, at: i64) -> Grant { 33 Grant { 34 subject: account(subject), 35 added_by: account(added_by), 36 created_at: UnixSeconds::new(at), 37 } 38} 39 40pub fn at(seconds: i64) -> UnixSeconds { 41 UnixSeconds::new(seconds) 42} 43 44pub fn owner_of(seed: u64) -> ActorId { 45 ActorId::from_secp256k1(signer(seed).public_key().as_bytes()) 46} 47 48pub fn rkey(value: &str) -> RepoRkey { 49 RepoRkey::new(value).unwrap() 50} 51 52pub fn did<T: std::str::FromStr>(suffix: &str) -> T 53where 54 T::Err: std::fmt::Debug, 55{ 56 format!("did:plc:{suffix}").parse().unwrap() 57} 58 59pub fn registration(owner: &str, key: &str, repo_id: &str, ts: i64) -> Registration { 60 Registration { 61 owner: OwnerDid::new(format!("did:plc:{owner}")).unwrap(), 62 rkey: rkey(key), 63 name: RepoName::new(key).unwrap(), 64 repo: RepoDid::new(format!("did:plc:{repo_id}")).unwrap(), 65 created_at: at(ts), 66 } 67} 68 69pub fn rename(owner_id: &str, key: &str, repo_id: &str) -> Rename { 70 Rename { 71 owner: did::<OwnerDid>(owner_id), 72 rkey: rkey(key), 73 name: RepoName::new(key).unwrap(), 74 repo: did::<RepoDid>(repo_id), 75 } 76} 77 78pub fn reopen(repo: Repo) -> Repo { 79 let path = repo.path().to_path_buf(); 80 drop(repo); 81 Repo::open(path).unwrap() 82} 83 84pub fn members_store( 85 seed: u64, 86 steps: &[(MembersChange, i64)], 87) -> (TempDir, Repo, K256Signer, CobId) { 88 let (dir, repo) = fixture(); 89 let key = signer(seed); 90 let store = CobStore::new(&repo); 91 let (first, first_at) = &steps[0]; 92 let created = store.create(&home(), first, &key, at(*first_at)).unwrap(); 93 steps[1..].iter().for_each(|(change, ts)| { 94 store 95 .update(&home(), created.object, change, &key, at(*ts)) 96 .unwrap(); 97 }); 98 (dir, repo, key, created.object) 99} 100 101pub fn build_members(seed: u64, steps: &[(MembersChange, i64)]) -> Members { 102 let (_dir, repo, _key, object) = members_store(seed, steps); 103 CobStore::new(&repo) 104 .get::<MembersCob>(object) 105 .unwrap() 106 .into_state() 107} 108 109pub fn write_cob_commit( 110 repo: &Repo, 111 type_name: &TypeName, 112 payload: &[u8], 113 parents: &[Oid], 114 author: &ActorId, 115 timestamp: i64, 116) -> Oid { 117 let git = repo.git(); 118 let payload_oid = git.write_blob(payload).unwrap().detach(); 119 let tree = gix::objs::Tree { 120 entries: vec![gix::objs::tree::Entry { 121 mode: gix::objs::tree::EntryKind::Blob.into(), 122 filename: "payload".into(), 123 oid: payload_oid, 124 }], 125 }; 126 let revision = git.write_object(tree).unwrap().detach(); 127 let identity = gix::actor::Signature { 128 name: "knot".into(), 129 email: "noreply@knot".into(), 130 time: gix::date::Time::new(timestamp, 0), 131 }; 132 let commit = gix::objs::Commit { 133 tree: revision, 134 parents: parents.iter().map(|oid| oid.object_id()).collect(), 135 author: identity.clone(), 136 committer: identity, 137 encoding: None, 138 message: Vec::new().into(), 139 extra_headers: vec![ 140 ("cob-type".into(), type_name.as_str().into()), 141 ("cob-author".into(), author.as_str().into()), 142 ("cob-sig".into(), "00".into()), 143 ], 144 }; 145 Oid::from(git.write_object(commit).unwrap().detach()) 146} 147 148pub fn cob_ref(type_name: &TypeName, object: CobId) -> RefName { 149 RefName::new(format!( 150 "refs/cobs/{}/{}", 151 type_name.as_str(), 152 object.oid().to_hex() 153 )) 154 .unwrap() 155} 156 157pub fn forked_members_object( 158 seed: u64, 159 root: (MembersChange, i64), 160 left: (MembersChange, i64), 161 right: (MembersChange, i64), 162 merge: (MembersChange, i64), 163) -> (TempDir, Repo, CobId) { 164 let (dir, repo) = fixture(); 165 let nsid = MembersChange::type_name(); 166 let author = ActorId::from_secp256k1(signer(seed).public_key().as_bytes()); 167 let enc = |c: &MembersChange| c.encode().unwrap(); 168 169 let root_oid = write_cob_commit(&repo, &nsid, &enc(&root.0), &[], &author, root.1); 170 let object = CobId::new(root_oid); 171 let left_oid = write_cob_commit(&repo, &nsid, &enc(&left.0), &[root_oid], &author, left.1); 172 let right_oid = write_cob_commit(&repo, &nsid, &enc(&right.0), &[root_oid], &author, right.1); 173 let merge_oid = write_cob_commit( 174 &repo, 175 &nsid, 176 &enc(&merge.0), 177 &[left_oid, right_oid], 178 &author, 179 merge.1, 180 ); 181 repo.update_ref(&RefUpdate::Create { 182 name: cob_ref(&nsid, object), 183 new: merge_oid, 184 }) 185 .unwrap(); 186 (dir, repo, object) 187} 188 189pub fn forked_members( 190 seed: u64, 191 root: (MembersChange, i64), 192 left: (MembersChange, i64), 193 right: (MembersChange, i64), 194 merge: (MembersChange, i64), 195) -> Result<Members, CobError> { 196 let (_dir, repo, object) = forked_members_object(seed, root, left, right, merge); 197 CobStore::new(&repo) 198 .get::<MembersCob>(object) 199 .map(|object| object.into_state()) 200} 201 202pub fn registry_with(repo: &Repo, key: &K256Signer, name: &str, repo_id: &str) -> CobId { 203 let store = CobStore::new(repo); 204 store 205 .create( 206 &home(), 207 &RegistryChange::Register(registration("nel", name, repo_id, 1)), 208 key, 209 at(1), 210 ) 211 .unwrap() 212 .object 213}