Skip to content

Commit b2f21db

Browse files
Merge pull request #21 from h-be/version-0-5-2-updates
Version 0 5 2 updates
2 parents 7cb2e77 + 1bef307 commit b2f21db

File tree

174 files changed

+5074
-3219
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+5074
-3219
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"rust-analyzer.cargo.features": [
3+
"mock"
4+
]
5+
}

dna/zomes/projects/src/project/edge/validate.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,35 @@ fn validate_create_entry_edge(validate_data: ValidateData) -> ExternResult<Valid
1919

2020
// parent goal, and child goal, must be determined to exist to pass validation
2121
if let Header::Create(_) = validate_data.element.header() {
22-
Ok(
23-
// parent goal
24-
match confirm_resolved_dependency::<Goal>(proposed_edge.parent_address.0.into())? {
25-
ValidateCallbackResult::Valid => {
26-
// child goal
27-
confirm_resolved_dependency::<Goal>(proposed_edge.child_address.0.into())?
22+
let parent_res = confirm_resolved_dependency::<Goal>(proposed_edge.parent_address.0.into())?;
23+
let child_res = confirm_resolved_dependency::<Goal>(proposed_edge.child_address.0.into())?;
24+
match (parent_res, child_res) {
25+
(ValidateCallbackResult::Valid, ValidateCallbackResult::Valid) => {
26+
Ok(ValidateCallbackResult::Valid)
27+
}
28+
(
29+
ValidateCallbackResult::UnresolvedDependencies(parent_dep),
30+
ValidateCallbackResult::UnresolvedDependencies(child_dep),
31+
) => Ok(ValidateCallbackResult::UnresolvedDependencies(vec![
32+
parent_dep.first().unwrap().to_owned(),
33+
child_dep.first().unwrap().to_owned(),
34+
])),
35+
(ValidateCallbackResult::UnresolvedDependencies(parent_dep), _) => {
36+
Ok(ValidateCallbackResult::UnresolvedDependencies(parent_dep))
37+
}
38+
(_, ValidateCallbackResult::UnresolvedDependencies(child_dep)) => {
39+
Ok(ValidateCallbackResult::UnresolvedDependencies(child_dep))
40+
}
41+
validate_callback_results => {
42+
if let ValidateCallbackResult::Invalid(e) = validate_callback_results.0 {
43+
// parent was invalid
44+
Ok(ValidateCallbackResult::Invalid(e))
45+
} else {
46+
// child was invalid
47+
Ok(validate_callback_results.1)
2848
}
29-
// we want to forward the validate_callback_result
30-
// back to Holochain since it contains a specific UnresolvedDependencies response
31-
// including the missing Hashes
32-
validate_callback_result => validate_callback_result,
33-
},
34-
)
49+
}
50+
}
3551
}
3652
// Holochain sent the wrong header!
3753
else {
@@ -112,25 +128,22 @@ pub mod tests {
112128
edge.child_address = goal_child_wrapped_header_hash.clone();
113129
*validate_data.element.as_entry_mut() = ElementEntry::Present(edge.clone().try_into().unwrap());
114130

115-
// act as if the parent_address Goal were missing, could not be resolved
131+
// act as if the parent_address and child_address Goals were missing, could not be resolved
116132
let mut mock_hdk = MockHdkT::new();
117133
mock_hdk
118134
.expect_get()
119-
.with(mockall::predicate::eq(GetInput::new(
120-
goal_parent_wrapped_header_hash.clone().0.into(),
121-
GetOptions::content(),
122-
)))
123-
.times(1)
135+
.times(2)
124136
.return_const(Ok(None));
125137

126138
set_hdk(mock_hdk);
127139

128140
// we should see that the ValidateCallbackResult is that there are UnresolvedDependencies
129-
// equal to the Hash of the parent Goal address
141+
// equal to the Hashes of the parent Goal address and the child Goal address
130142
assert_eq!(
131143
super::validate_create_entry_edge(validate_data.clone()),
132144
Ok(ValidateCallbackResult::UnresolvedDependencies(vec![
133-
goal_parent_wrapped_header_hash.clone().0.into()
145+
goal_parent_wrapped_header_hash.clone().0.into(),
146+
goal_child_wrapped_header_hash.clone().0.into()
134147
])),
135148
);
136149

dna/zomes/projects/src/project/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ pub enum Error {
66
#[error("Element with invalid header")]
77
WrongHeader,
88

9-
#[error("Element is missing its Entry")]
9+
#[error("Element missing its Entry")]
1010
EntryMissing,
1111

1212
#[error("Only one of this entry type should exist and an existing one was found")]

dna/zomes/projects/src/project/fixtures.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ pub(crate) mod fixtures {
44
use crate::project::{
55
edge::crud::Edge, entry_point::crud::EntryPoint, goal::crud::TimeFrame,
66
goal_comment::crud::GoalComment, goal_member::crud::GoalMember, goal_vote::crud::GoalVote,
7-
member::entry::Member, project_meta::crud::ProjectMeta,
7+
member::entry::Member, project_meta::crud::{ProjectMeta, PriorityMode},
88
};
99
use ::fixt::prelude::*;
1010
use dna_help::{WrappedAgentPubKey, WrappedHeaderHash};
1111
use hdk::prelude::*;
1212

13-
// why can't I put this one in dna_help crate?
1413
fixturator!(
1514
WrappedHeaderHash;
1615
constructor fn new(HeaderHash);
@@ -53,15 +52,21 @@ pub(crate) mod fixtures {
5352

5453
fixturator!(
5554
ProjectMeta;
56-
constructor fn new(WrappedAgentPubKey, f64, String, OptionString, String, bool);
55+
constructor fn new(WrappedAgentPubKey, f64, String, OptionString, String, bool, PriorityMode, VecWrappedHeaderHash);
5756
);
5857

58+
type VecWrappedHeaderHash = Vec<WrappedHeaderHash>;
5959
type OptionWrappedAgentPubKey = Option<WrappedAgentPubKey>;
6060
type OptionString = Option<String>;
6161
type Optionf64 = Option<f64>;
6262
type OptionVecString = Option<Vec<String>>;
6363
type OptionTimeFrame = Option<TimeFrame>;
6464

65+
fixturator!(
66+
PriorityMode;
67+
unit variants [ Universal Vote ] empty Universal;
68+
);
69+
6570
fixturator!(
6671
TimeFrame;
6772
constructor fn new(f64, f64);
@@ -77,6 +82,19 @@ pub(crate) mod fixtures {
7782
unit variants [Root Trunk Branch Leaf NoHierarchy ] empty NoHierarchy;
7883
);
7984

85+
fixturator!(
86+
VecWrappedHeaderHash;
87+
curve Empty {
88+
Vec::new()
89+
};
90+
curve Unpredictable {
91+
vec![WrappedHeaderHashFixturator::new(Unpredictable).next().unwrap()]
92+
};
93+
curve Predictable {
94+
vec![WrappedHeaderHashFixturator::new(Predictable).next().unwrap()]
95+
};
96+
);
97+
8098
fixturator!(
8199
OptionWrappedAgentPubKey;
82100
curve Empty {

dna/zomes/projects/src/project/goal/crud.rs

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl Goal {
7272
}
7373

7474
#[derive(Debug, Serialize, Deserialize, SerializedBytes, Clone, PartialEq)]
75-
pub struct UIEnum(String);
75+
pub struct UIEnum(pub String);
7676

7777
#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
7878
#[serde(from = "UIEnum")]
@@ -163,10 +163,45 @@ crud!(
163163
convert_to_receiver_signal
164164
);
165165

166+
167+
168+
#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
169+
#[serde(from = "UIEnum")]
170+
#[serde(into = "UIEnum")]
171+
pub enum RelationInput {
172+
ExistingGoalAsChild,
173+
ExistingGoalAsParent
174+
}
175+
impl From<UIEnum> for RelationInput {
176+
fn from(ui_enum: UIEnum) -> Self {
177+
match ui_enum.0.as_str() {
178+
"ExistingGoalAsChild" => Self::ExistingGoalAsChild,
179+
"ExistingGoalAsParent" => Self::ExistingGoalAsParent,
180+
_ => Self::ExistingGoalAsChild,
181+
}
182+
}
183+
}
184+
impl From<RelationInput> for UIEnum {
185+
fn from(relation_input: RelationInput) -> Self {
186+
Self(relation_input.to_string())
187+
}
188+
}
189+
impl fmt::Display for RelationInput {
190+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
191+
write!(f, "{:?}", self)
192+
}
193+
}
194+
195+
#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
196+
pub struct LinkedGoalDetails {
197+
goal_address: WrappedHeaderHash,
198+
relation: RelationInput
199+
}
200+
166201
#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
167202
pub struct CreateGoalWithEdgeInput {
168203
entry: Goal,
169-
maybe_parent_address: Option<WrappedHeaderHash>,
204+
maybe_linked_goal: Option<LinkedGoalDetails>,
170205
}
171206

172207
#[derive(Serialize, Deserialize, Debug, SerializedBytes, Clone, PartialEq)]
@@ -189,11 +224,18 @@ pub fn create_goal_with_edge(
189224
) -> ExternResult<CreateGoalWithEdgeOutput> {
190225
// false to say don't send a signal
191226
let wire_entry: GoalWireEntry = inner_create_goal(input.entry.clone(), false)?;
192-
let maybe_edge: Option<EdgeWireEntry> = match input.maybe_parent_address {
193-
Some(header_hash) => {
227+
let new_goal_address = wire_entry.address.clone();
228+
let maybe_edge: Option<EdgeWireEntry> = match input.maybe_linked_goal {
229+
Some(linked_goal_details) => {
230+
let (parent_address, child_address) = match linked_goal_details.relation {
231+
// new goal becomes parent
232+
RelationInput::ExistingGoalAsChild => (new_goal_address, linked_goal_details.goal_address),
233+
// new goal becomes child
234+
RelationInput::ExistingGoalAsParent => (linked_goal_details.goal_address, new_goal_address)
235+
};
194236
let edge = Edge {
195-
parent_address: header_hash,
196-
child_address: wire_entry.address.clone(),
237+
parent_address,
238+
child_address,
197239
randomizer: sys_time()?.as_secs_f64(),
198240
is_imported: false
199241
};

dna/zomes/projects/src/project/goal/validate.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,16 @@ fn validate_update_entry_goal(validate_data: ValidateData) -> ExternResult<Valid
5555
// `user_hash` still matches that original author
5656
if let Header::Update(header) = validate_data.element.header() {
5757
match resolve_dependency::<Goal>(header.original_header_address.clone().into())? {
58-
Ok(ResolvedDependency(el, _)) => {
58+
Ok(ResolvedDependency(_el, goal)) => {
5959
// the final return value
6060
// if this passes, all have passed
6161

6262
// here we are checking to make sure that
6363
// this user is not suggesting that someone other than
6464
// the original author of the original goal WAS the original
65-
validate_value_matches_original_author(&proposed_entry.user_hash.0, &el)
65+
validate_value_matches_original_author(&proposed_entry.user_hash.0, &goal.user_hash.0)
6666
}
67-
// the unresolved dependency case
67+
// the unresolved dependency case and invalid case
6868
Err(validate_callback_result) => validate_callback_result,
6969
}
7070
} else {
@@ -206,7 +206,7 @@ pub mod tests {
206206
// to know this, we need to resolve that dependency
207207
goal.user_edit_hash = Some(WrappedAgentPubKey::new(
208208
update_header.author.as_hash().clone(),
209-
));
209+
));
210210
// update the goal value in the validate_data
211211
*validate_data.element.as_entry_mut() = ElementEntry::Present(goal.clone().try_into().unwrap());
212212

@@ -266,15 +266,15 @@ pub mod tests {
266266
// SUCCESS case
267267
// the element exists and deserializes
268268
// user_edit_hash is Some(the author)
269-
// original_header_address exists, and the author
270-
// of that original header
269+
// original_header_address exists, and the value
270+
// `user_hash` of the original Goal
271271
// is equal to the new `user_hash` value
272272
// -> good to go
273273
// we should see that the ValidateCallbackResult
274274
// is finally valid
275275

276-
// set the user_hash on the goal equal to the "original header author address"
277-
goal.user_hash = WrappedAgentPubKey::new(original_goal_element.header().author().clone());
276+
// set the user_hash on the goal equal to the original goals user_hash property
277+
goal.user_hash = original_goal.user_hash.clone();
278278
*validate_data.element.as_entry_mut() = ElementEntry::Present(goal.clone().try_into().unwrap());
279279

280280
let mut mock_hdk = MockHdkT::new();

dna/zomes/projects/src/project/goal_comment/validate.rs

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ fn validate_update_entry_goal_comment(
5757
match resolve_dependency::<GoalComment>(
5858
header.original_header_address.clone().into(),
5959
)? {
60-
Ok(ResolvedDependency(el, _)) => {
60+
Ok(ResolvedDependency(_el, goal_comment)) => {
6161
// the final return value
6262
// if this passes, all have passed
6363

6464
// here we are checking to make sure that
6565
// only original author can make this update
66-
validate_value_matches_original_author_for_edit(&header.author, &el)
66+
validate_value_matches_original_author_for_edit(
67+
&header.author,
68+
&goal_comment.agent_address.0,
69+
)
6770
}
6871
// the unresolved dependency case
6972
Err(validate_callback_result) => validate_callback_result,
@@ -183,7 +186,7 @@ pub mod tests {
183186
// the parent goal is found/exists
184187
// agent_address refers to the agent committing
185188
// -> good to go
186-
189+
187190
// make the agent_address valid by making it equal the
188191
// AgentPubKey of the agent committing
189192
goal_comment.agent_address = WrappedAgentPubKey::new(create_header.author.as_hash().clone());
@@ -285,8 +288,8 @@ pub mod tests {
285288
let original_goal_comment = fixt!(GoalComment);
286289
// but due to being random, it will have a different author
287290
// than our Update header
288-
let mut goal_comment_element = fixt!(Element);
289-
*goal_comment_element.as_entry_mut() =
291+
let mut original_goal_comment_element = fixt!(Element);
292+
*original_goal_comment_element.as_entry_mut() =
290293
ElementEntry::Present(original_goal_comment.clone().try_into().unwrap());
291294

292295
let mut mock_hdk = MockHdkT::new();
@@ -298,7 +301,7 @@ pub mod tests {
298301
GetOptions::content(),
299302
)))
300303
.times(1)
301-
.return_const(Ok(Some(goal_comment_element.clone())));
304+
.return_const(Ok(Some(original_goal_comment_element.clone())));
302305

303306
set_hdk(mock_hdk);
304307

@@ -313,16 +316,12 @@ pub mod tests {
313316
// the original GoalComment header and entry exist
314317
// and the author of the update matches the original author
315318
// -> good to go
316-
let original_goal_comment = fixt!(GoalComment);
317-
let mut goal_comment_element = fixt!(Element);
318-
let mut original_create_header = fixt!(Create);
319-
// make the authors equal
320-
original_create_header = Create {
321-
author: update_header.author.as_hash().clone(),
322-
..original_create_header
323-
};
324-
*goal_comment_element.as_header_mut() = Header::Create(original_create_header.clone());
325-
*goal_comment_element.as_entry_mut() =
319+
let mut original_goal_comment = fixt!(GoalComment);
320+
let mut original_goal_comment_element = fixt!(Element);
321+
// make the author equal to the current `user_hash` value
322+
// on the Goal in validate_data
323+
original_goal_comment.agent_address = WrappedAgentPubKey::new(update_header.author.as_hash().clone());
324+
*original_goal_comment_element.as_entry_mut() =
326325
ElementEntry::Present(original_goal_comment.clone().try_into().unwrap());
327326

328327
let mut mock_hdk = MockHdkT::new();
@@ -334,7 +333,7 @@ pub mod tests {
334333
GetOptions::content(),
335334
)))
336335
.times(1)
337-
.return_const(Ok(Some(goal_comment_element.clone())));
336+
.return_const(Ok(Some(original_goal_comment_element.clone())));
338337

339338
set_hdk(mock_hdk);
340339

0 commit comments

Comments
 (0)