1- use super :: error:: { EntityApiErrorKind , Error } ;
1+ use super :: {
2+ error:: { EntityApiErrorKind , Error } ,
3+ organization,
4+ } ;
25use crate :: user;
36use chrono:: Utc ;
47use entity:: {
@@ -16,17 +19,42 @@ use slugify::slugify;
1619
1720pub async fn create (
1821 db : & impl ConnectionTrait ,
22+ organization_id : Id ,
1923 coaching_relationship_model : Model ,
20- ) -> Result < Model , Error > {
24+ ) -> Result < CoachingRelationshipWithUserNames , Error > {
2125 debug ! (
2226 "New Coaching Relationship Model to be inserted: {:?}" ,
2327 coaching_relationship_model
2428 ) ;
2529
30+ let coach = user:: find_by_id ( db, coaching_relationship_model. coach_id ) . await ?;
31+ let coachee = user:: find_by_id ( db, coaching_relationship_model. coachee_id ) . await ?;
32+
33+ let coach_organization_ids = organization:: find_by_user ( db, coach. id )
34+ . await ?
35+ . iter ( )
36+ . map ( |org| org. id )
37+ . collect :: < Vec < Id > > ( ) ;
38+ let coachee_organization_ids = organization:: find_by_user ( db, coachee. id )
39+ . await ?
40+ . iter ( )
41+ . map ( |org| org. id )
42+ . collect :: < Vec < Id > > ( ) ;
43+
44+ // Check that the coach and coachee belong to the correct organization
45+ if !coach_organization_ids. contains ( & organization_id)
46+ || !coachee_organization_ids. contains ( & organization_id)
47+ {
48+ error ! ( "Coach and coachee do not belong to the correct organization, not creating requested new coaching relationship between coach: {:?} and coachee: {:?} for organization: {:?}." , coaching_relationship_model. coach_id, coaching_relationship_model. coachee_id, organization_id) ;
49+ return Err ( Error {
50+ source : None ,
51+ error_kind : EntityApiErrorKind :: ValidationError ,
52+ } ) ;
53+ }
54+
2655 // Coaching Relationship must be unique within the context of an organization
2756 // Note: this is enforced at the database level as well
28- let existing_coaching_relationships =
29- find_by_organization ( db, coaching_relationship_model. organization_id ) . await ?;
57+ let existing_coaching_relationships = find_by_organization ( db, organization_id) . await ?;
3058 let existing_coaching_relationship = existing_coaching_relationships. iter ( ) . find ( |cr| {
3159 cr. coach_id == coaching_relationship_model. coach_id
3260 && cr. coachee_id == coaching_relationship_model. coachee_id
@@ -46,15 +74,27 @@ pub async fn create(
4674 let slug = slugify ! ( format!( "{} {}" , coach. first_name, coachee. first_name) . as_str( ) ) ;
4775
4876 let coaching_relationship_active_model: ActiveModel = ActiveModel {
49- organization_id : Set ( coaching_relationship_model . organization_id ) ,
77+ organization_id : Set ( organization_id) ,
5078 coach_id : Set ( coaching_relationship_model. coach_id ) ,
5179 coachee_id : Set ( coaching_relationship_model. coachee_id ) ,
5280 slug : Set ( slug) ,
5381 created_at : Set ( now. into ( ) ) ,
5482 updated_at : Set ( now. into ( ) ) ,
5583 ..Default :: default ( )
5684 } ;
57- Ok ( coaching_relationship_active_model. insert ( db) . await ?)
85+ let inserted: Model = coaching_relationship_active_model. insert ( db) . await ?;
86+
87+ Ok ( CoachingRelationshipWithUserNames {
88+ id : inserted. id ,
89+ coach_id : inserted. coach_id ,
90+ coachee_id : inserted. coachee_id ,
91+ coach_first_name : coach. first_name ,
92+ coach_last_name : coach. last_name ,
93+ coachee_first_name : coachee. first_name ,
94+ coachee_last_name : coachee. last_name ,
95+ created_at : inserted. created_at ,
96+ updated_at : inserted. updated_at ,
97+ } )
5898}
5999
60100pub async fn find_by_id ( db : & DatabaseConnection , id : Id ) -> Result < Model , Error > {
@@ -206,7 +246,7 @@ pub async fn delete_by_user_id(db: &impl ConnectionTrait, user_id: Id) -> Result
206246
207247// A convenient combined struct that holds the results of looking up the Users associated
208248// with the coach/coachee ids. This should be used as an implementation detail only.
209- #[ derive( FromQueryResult , Debug ) ]
249+ #[ derive( FromQueryResult , Debug , PartialEq ) ]
210250pub struct CoachingRelationshipWithUserNames {
211251 pub id : Id ,
212252 pub coach_id : Id ,
@@ -337,26 +377,76 @@ mod tests {
337377 #[ tokio:: test]
338378 async fn create_returns_validation_error_for_duplicate_relationship ( ) -> Result < ( ) , Error > {
339379 use entity:: coaching_relationships:: Model ;
340- use sea_orm:: { DatabaseBackend , MockDatabase , MockExecResult } ;
380+ use sea_orm:: { DatabaseBackend , MockDatabase } ;
341381
342382 let organization_id = Id :: new_v4 ( ) ;
343383 let coach_id = Id :: new_v4 ( ) ;
344384 let coachee_id = Id :: new_v4 ( ) ;
385+ let coach_organization_id = Id :: new_v4 ( ) ;
386+ let coachee_organization_id = Id :: new_v4 ( ) ;
387+
388+ let coach_user = entity:: users:: Model {
389+ id : coach_id. clone ( ) ,
390+ first_name : "Coach" . to_string ( ) ,
391+ last_name : "User" . to_string ( ) ,
392+ email : "[email protected] " . to_string ( ) , 393+ password : "hash" . to_string ( ) ,
394+ display_name : Some ( "Coach User" . to_string ( ) ) ,
395+ github_username : Some ( "coach_user" . to_string ( ) ) ,
396+ role : entity:: users:: Role :: User ,
397+ github_profile_url : Some ( "https://github.com/coach_user" . to_string ( ) ) ,
398+ created_at : chrono:: Utc :: now ( ) . into ( ) ,
399+ updated_at : chrono:: Utc :: now ( ) . into ( ) ,
400+ } ;
401+
402+ let coachee_user = entity:: users:: Model {
403+ id : coachee_id. clone ( ) ,
404+ first_name : "Coachee" . to_string ( ) ,
405+ last_name : "User" . to_string ( ) ,
406+ email : "[email protected] " . to_string ( ) , 407+ password : "hash" . to_string ( ) ,
408+ display_name : Some ( "Coachee User" . to_string ( ) ) ,
409+ github_username : Some ( "coachee_user" . to_string ( ) ) ,
410+ role : entity:: users:: Role :: User ,
411+ github_profile_url : Some ( "https://github.com/coachee_user" . to_string ( ) ) ,
412+ created_at : chrono:: Utc :: now ( ) . into ( ) ,
413+ updated_at : chrono:: Utc :: now ( ) . into ( ) ,
414+ } ;
415+
416+ let coaching_relationships = vec ! [ Model {
417+ id: Id :: new_v4( ) ,
418+ organization_id: organization_id. clone( ) ,
419+ coach_id: coach_id. clone( ) ,
420+ coachee_id: coachee_id. clone( ) ,
421+ slug: "coach-coachee" . to_string( ) ,
422+ created_at: chrono:: Utc :: now( ) . into( ) ,
423+ updated_at: chrono:: Utc :: now( ) . into( ) ,
424+ } ] ;
425+
426+ let coach_organization = entity:: organizations:: Model {
427+ id : coach_organization_id,
428+ name : "Organization" . to_string ( ) ,
429+ slug : "organization" . to_string ( ) ,
430+ logo : None ,
431+ created_at : chrono:: Utc :: now ( ) . into ( ) ,
432+ updated_at : chrono:: Utc :: now ( ) . into ( ) ,
433+ } ;
434+
435+ let coachee_organization = entity:: organizations:: Model {
436+ id : coachee_organization_id,
437+ name : "Organization" . to_string ( ) ,
438+ slug : "organization" . to_string ( ) ,
439+ logo : None ,
440+ created_at : chrono:: Utc :: now ( ) . into ( ) ,
441+ updated_at : chrono:: Utc :: now ( ) . into ( ) ,
442+ } ;
345443
346444 let db = MockDatabase :: new ( DatabaseBackend :: Postgres )
347- . append_query_results ( vec ! [ vec![ Model {
348- id: Id :: new_v4( ) ,
349- organization_id: organization_id. clone( ) ,
350- coach_id: coach_id. clone( ) ,
351- coachee_id: coachee_id. clone( ) ,
352- slug: "coach-coachee" . to_string( ) ,
353- created_at: chrono:: Utc :: now( ) . into( ) ,
354- updated_at: chrono:: Utc :: now( ) . into( ) ,
355- } ] ] )
356- . append_exec_results ( vec ! [ MockExecResult {
357- last_insert_id: 0 ,
358- rows_affected: 1 ,
359- } ] )
445+ . append_query_results ( vec ! [ vec![ coach_user] ] )
446+ . append_query_results ( vec ! [ vec![ coachee_user] ] )
447+ . append_query_results ( vec ! [ vec![ coach_organization] ] )
448+ . append_query_results ( vec ! [ vec![ coachee_organization] ] )
449+ . append_query_results ( vec ! [ coaching_relationships] )
360450 . into_connection ( ) ;
361451
362452 let model = Model {
@@ -369,7 +459,8 @@ mod tests {
369459 updated_at : chrono:: Utc :: now ( ) . into ( ) ,
370460 } ;
371461
372- let result = create ( & db, model) . await ;
462+ let result = create ( & db, organization_id, model) . await ;
463+ println ! ( "Result: {:?}" , result) ;
373464 assert ! (
374465 result
375466 == Err ( Error {
0 commit comments