]> Untitled Git - lemmy.git/blob - crates/db_schema/src/impls/activity.rs
Moving settings to Database. (#2492)
[lemmy.git] / crates / db_schema / src / impls / activity.rs
1 use crate::{newtypes::DbUrl, source::activity::*, traits::Crud};
2 use diesel::{
3   dsl::*,
4   result::{DatabaseErrorKind, Error},
5   *,
6 };
7 use serde_json::Value;
8
9 impl Crud for Activity {
10   type InsertForm = ActivityInsertForm;
11   type UpdateForm = ActivityUpdateForm;
12   type IdType = i32;
13   fn read(conn: &mut PgConnection, activity_id: i32) -> Result<Self, Error> {
14     use crate::schema::activity::dsl::*;
15     activity.find(activity_id).first::<Self>(conn)
16   }
17
18   fn create(conn: &mut PgConnection, new_activity: &Self::InsertForm) -> Result<Self, Error> {
19     use crate::schema::activity::dsl::*;
20     insert_into(activity)
21       .values(new_activity)
22       .get_result::<Self>(conn)
23   }
24
25   fn update(
26     conn: &mut PgConnection,
27     activity_id: i32,
28     new_activity: &Self::UpdateForm,
29   ) -> Result<Self, Error> {
30     use crate::schema::activity::dsl::*;
31     diesel::update(activity.find(activity_id))
32       .set(new_activity)
33       .get_result::<Self>(conn)
34   }
35   fn delete(conn: &mut PgConnection, activity_id: i32) -> Result<usize, Error> {
36     use crate::schema::activity::dsl::*;
37     diesel::delete(activity.find(activity_id)).execute(conn)
38   }
39 }
40
41 impl Activity {
42   /// Returns true if the insert was successful
43   // TODO this should probably just be changed to an upsert on_conflict, rather than an error
44   pub fn insert(
45     conn: &mut PgConnection,
46     ap_id: DbUrl,
47     data: Value,
48     local: bool,
49     sensitive: Option<bool>,
50   ) -> Result<bool, Error> {
51     let activity_form = ActivityInsertForm {
52       ap_id,
53       data,
54       local: Some(local),
55       sensitive,
56       updated: None,
57     };
58     match Activity::create(conn, &activity_form) {
59       Ok(_) => Ok(true),
60       Err(e) => {
61         if let Error::DatabaseError(DatabaseErrorKind::UniqueViolation, _) = e {
62           return Ok(false);
63         }
64         Err(e)
65       }
66     }
67   }
68
69   pub fn read_from_apub_id(conn: &mut PgConnection, object_id: &DbUrl) -> Result<Activity, Error> {
70     use crate::schema::activity::dsl::*;
71     activity.filter(ap_id.eq(object_id)).first::<Self>(conn)
72   }
73
74   pub fn delete_olds(conn: &mut PgConnection) -> Result<usize, Error> {
75     use crate::schema::activity::dsl::*;
76     diesel::delete(activity.filter(published.lt(now - 6.months()))).execute(conn)
77   }
78 }
79
80 #[cfg(test)]
81 mod tests {
82   use super::*;
83   use crate::{
84     newtypes::DbUrl,
85     source::{
86       activity::{Activity, ActivityInsertForm},
87       instance::Instance,
88       person::{Person, PersonInsertForm},
89     },
90     utils::establish_unpooled_connection,
91   };
92   use serde_json::Value;
93   use serial_test::serial;
94   use url::Url;
95
96   #[test]
97   #[serial]
98   fn test_crud() {
99     let conn = &mut establish_unpooled_connection();
100
101     let inserted_instance = Instance::create(conn, "my_domain.tld").unwrap();
102
103     let creator_form = PersonInsertForm::builder()
104       .name("activity_creator_ pm".into())
105       .public_key("pubkey".to_string())
106       .instance_id(inserted_instance.id)
107       .build();
108
109     let inserted_creator = Person::create(conn, &creator_form).unwrap();
110
111     let ap_id: DbUrl = Url::parse(
112       "https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c",
113     )
114     .unwrap()
115     .into();
116     let test_json: Value = serde_json::from_str(
117       r#"{
118     "@context": "https://www.w3.org/ns/activitystreams",
119     "id": "https://enterprise.lemmy.ml/activities/delete/f1b5d57c-80f8-4e03-a615-688d552e946c",
120     "type": "Delete",
121     "actor": "https://enterprise.lemmy.ml/u/riker",
122     "to": "https://www.w3.org/ns/activitystreams#Public",
123     "cc": [
124         "https://enterprise.lemmy.ml/c/main/"
125     ],
126     "object": "https://enterprise.lemmy.ml/post/32"
127     }"#,
128     )
129     .unwrap();
130     let activity_form = ActivityInsertForm {
131       ap_id: ap_id.clone(),
132       data: test_json.to_owned(),
133       local: Some(true),
134       sensitive: Some(false),
135       updated: None,
136     };
137
138     let inserted_activity = Activity::create(conn, &activity_form).unwrap();
139
140     let expected_activity = Activity {
141       ap_id: ap_id.clone(),
142       id: inserted_activity.id,
143       data: test_json,
144       local: true,
145       sensitive: Some(false),
146       published: inserted_activity.published,
147       updated: None,
148     };
149
150     let read_activity = Activity::read(conn, inserted_activity.id).unwrap();
151     let read_activity_by_apub_id = Activity::read_from_apub_id(conn, &ap_id).unwrap();
152     Person::delete(conn, inserted_creator.id).unwrap();
153     Activity::delete(conn, inserted_activity.id).unwrap();
154
155     assert_eq!(expected_activity, read_activity);
156     assert_eq!(expected_activity, read_activity_by_apub_id);
157     assert_eq!(expected_activity, inserted_activity);
158   }
159 }