]> Untitled Git - lemmy.git/blob - crates/db_views/src/registration_application_view.rs
Diesel 2.0.0 upgrade (#2452)
[lemmy.git] / crates / db_views / src / registration_application_view.rs
1 use crate::structs::RegistrationApplicationView;
2 use diesel::{dsl::count, result::Error, *};
3 use lemmy_db_schema::{
4   schema::{local_user, person, registration_application},
5   source::{
6     local_user::{LocalUser, LocalUserSettings},
7     person::{Person, PersonSafe},
8     registration_application::RegistrationApplication,
9   },
10   traits::{ToSafe, ToSafeSettings, ViewToVec},
11   utils::limit_and_offset,
12 };
13 use typed_builder::TypedBuilder;
14
15 type RegistrationApplicationViewTuple = (
16   RegistrationApplication,
17   LocalUserSettings,
18   PersonSafe,
19   Option<PersonSafe>,
20 );
21
22 impl RegistrationApplicationView {
23   pub fn read(conn: &mut PgConnection, registration_application_id: i32) -> Result<Self, Error> {
24     let person_alias_1 = diesel::alias!(person as person1);
25
26     let (registration_application, creator_local_user, creator, admin) =
27       registration_application::table
28         .find(registration_application_id)
29         .inner_join(
30           local_user::table.on(registration_application::local_user_id.eq(local_user::id)),
31         )
32         .inner_join(person::table.on(local_user::person_id.eq(person::id)))
33         .left_join(
34           person_alias_1
35             .on(registration_application::admin_id.eq(person_alias_1.field(person::id).nullable())),
36         )
37         .order_by(registration_application::published.desc())
38         .select((
39           registration_application::all_columns,
40           LocalUser::safe_settings_columns_tuple(),
41           Person::safe_columns_tuple(),
42           person_alias_1
43             .fields(Person::safe_columns_tuple())
44             .nullable(),
45         ))
46         .first::<RegistrationApplicationViewTuple>(conn)?;
47
48     Ok(RegistrationApplicationView {
49       registration_application,
50       creator_local_user,
51       creator,
52       admin,
53     })
54   }
55
56   /// Returns the current unread registration_application count
57   pub fn get_unread_count(
58     conn: &mut PgConnection,
59     verified_email_only: bool,
60   ) -> Result<i64, Error> {
61     let person_alias_1 = diesel::alias!(person as person1);
62
63     let mut query = registration_application::table
64       .inner_join(local_user::table.on(registration_application::local_user_id.eq(local_user::id)))
65       .inner_join(person::table.on(local_user::person_id.eq(person::id)))
66       .left_join(
67         person_alias_1
68           .on(registration_application::admin_id.eq(person_alias_1.field(person::id).nullable())),
69       )
70       .filter(registration_application::admin_id.is_null())
71       .into_boxed();
72
73     if verified_email_only {
74       query = query.filter(local_user::email_verified.eq(true))
75     }
76
77     query
78       .select(count(registration_application::id))
79       .first::<i64>(conn)
80   }
81 }
82
83 #[derive(TypedBuilder)]
84 #[builder(field_defaults(default))]
85 pub struct RegistrationApplicationQuery<'a> {
86   #[builder(!default)]
87   conn: &'a mut PgConnection,
88   unread_only: Option<bool>,
89   verified_email_only: Option<bool>,
90   page: Option<i64>,
91   limit: Option<i64>,
92 }
93
94 impl<'a> RegistrationApplicationQuery<'a> {
95   pub fn list(self) -> Result<Vec<RegistrationApplicationView>, Error> {
96     let person_alias_1 = diesel::alias!(person as person1);
97
98     let mut query = registration_application::table
99       .inner_join(local_user::table.on(registration_application::local_user_id.eq(local_user::id)))
100       .inner_join(person::table.on(local_user::person_id.eq(person::id)))
101       .left_join(
102         person_alias_1
103           .on(registration_application::admin_id.eq(person_alias_1.field(person::id).nullable())),
104       )
105       .order_by(registration_application::published.desc())
106       .select((
107         registration_application::all_columns,
108         LocalUser::safe_settings_columns_tuple(),
109         Person::safe_columns_tuple(),
110         person_alias_1
111           .fields(Person::safe_columns_tuple())
112           .nullable(),
113       ))
114       .into_boxed();
115
116     if self.unread_only.unwrap_or(false) {
117       query = query.filter(registration_application::admin_id.is_null())
118     }
119
120     if self.verified_email_only.unwrap_or(false) {
121       query = query.filter(local_user::email_verified.eq(true))
122     }
123
124     let (limit, offset) = limit_and_offset(self.page, self.limit)?;
125
126     query = query
127       .limit(limit)
128       .offset(offset)
129       .order_by(registration_application::published.desc());
130
131     let res = query.load::<RegistrationApplicationViewTuple>(self.conn)?;
132
133     Ok(RegistrationApplicationView::from_tuple_to_vec(res))
134   }
135 }
136
137 impl ViewToVec for RegistrationApplicationView {
138   type DbTuple = RegistrationApplicationViewTuple;
139   fn from_tuple_to_vec(items: Vec<Self::DbTuple>) -> Vec<Self> {
140     items
141       .into_iter()
142       .map(|a| Self {
143         registration_application: a.0,
144         creator_local_user: a.1,
145         creator: a.2,
146         admin: a.3,
147       })
148       .collect::<Vec<Self>>()
149   }
150 }
151
152 #[cfg(test)]
153 mod tests {
154   use crate::registration_application_view::{
155     RegistrationApplicationQuery,
156     RegistrationApplicationView,
157   };
158   use lemmy_db_schema::{
159     source::{
160       local_user::{LocalUser, LocalUserForm, LocalUserSettings},
161       person::*,
162       registration_application::{RegistrationApplication, RegistrationApplicationForm},
163     },
164     traits::Crud,
165     utils::establish_unpooled_connection,
166   };
167   use serial_test::serial;
168
169   #[test]
170   #[serial]
171   fn test_crud() {
172     let conn = &mut establish_unpooled_connection();
173
174     let timmy_person_form = PersonForm {
175       name: "timmy_rav".into(),
176       admin: Some(true),
177       public_key: Some("pubkey".to_string()),
178       ..PersonForm::default()
179     };
180
181     let inserted_timmy_person = Person::create(conn, &timmy_person_form).unwrap();
182
183     let timmy_local_user_form = LocalUserForm {
184       person_id: Some(inserted_timmy_person.id),
185       password_encrypted: Some("nada".to_string()),
186       ..LocalUserForm::default()
187     };
188
189     let _inserted_timmy_local_user = LocalUser::create(conn, &timmy_local_user_form).unwrap();
190
191     let sara_person_form = PersonForm {
192       name: "sara_rav".into(),
193       public_key: Some("pubkey".to_string()),
194       ..PersonForm::default()
195     };
196
197     let inserted_sara_person = Person::create(conn, &sara_person_form).unwrap();
198
199     let sara_local_user_form = LocalUserForm {
200       person_id: Some(inserted_sara_person.id),
201       password_encrypted: Some("nada".to_string()),
202       ..LocalUserForm::default()
203     };
204
205     let inserted_sara_local_user = LocalUser::create(conn, &sara_local_user_form).unwrap();
206
207     // Sara creates an application
208     let sara_app_form = RegistrationApplicationForm {
209       local_user_id: Some(inserted_sara_local_user.id),
210       answer: Some("LET ME IIIIINN".to_string()),
211       ..RegistrationApplicationForm::default()
212     };
213
214     let sara_app = RegistrationApplication::create(conn, &sara_app_form).unwrap();
215
216     let read_sara_app_view = RegistrationApplicationView::read(conn, sara_app.id).unwrap();
217
218     let jess_person_form = PersonForm {
219       name: "jess_rav".into(),
220       public_key: Some("pubkey".to_string()),
221       ..PersonForm::default()
222     };
223
224     let inserted_jess_person = Person::create(conn, &jess_person_form).unwrap();
225
226     let jess_local_user_form = LocalUserForm {
227       person_id: Some(inserted_jess_person.id),
228       password_encrypted: Some("nada".to_string()),
229       ..LocalUserForm::default()
230     };
231
232     let inserted_jess_local_user = LocalUser::create(conn, &jess_local_user_form).unwrap();
233
234     // Sara creates an application
235     let jess_app_form = RegistrationApplicationForm {
236       local_user_id: Some(inserted_jess_local_user.id),
237       answer: Some("LET ME IIIIINN".to_string()),
238       ..RegistrationApplicationForm::default()
239     };
240
241     let jess_app = RegistrationApplication::create(conn, &jess_app_form).unwrap();
242
243     let read_jess_app_view = RegistrationApplicationView::read(conn, jess_app.id).unwrap();
244
245     let mut expected_sara_app_view = RegistrationApplicationView {
246       registration_application: sara_app.to_owned(),
247       creator_local_user: LocalUserSettings {
248         id: inserted_sara_local_user.id,
249         person_id: inserted_sara_local_user.person_id,
250         email: inserted_sara_local_user.email,
251         show_nsfw: inserted_sara_local_user.show_nsfw,
252         theme: inserted_sara_local_user.theme,
253         default_sort_type: inserted_sara_local_user.default_sort_type,
254         default_listing_type: inserted_sara_local_user.default_listing_type,
255         interface_language: inserted_sara_local_user.interface_language,
256         show_avatars: inserted_sara_local_user.show_avatars,
257         send_notifications_to_email: inserted_sara_local_user.send_notifications_to_email,
258         validator_time: inserted_sara_local_user.validator_time,
259         show_bot_accounts: inserted_sara_local_user.show_bot_accounts,
260         show_scores: inserted_sara_local_user.show_scores,
261         show_read_posts: inserted_sara_local_user.show_read_posts,
262         show_new_post_notifs: inserted_sara_local_user.show_new_post_notifs,
263         email_verified: inserted_sara_local_user.email_verified,
264         accepted_application: inserted_sara_local_user.accepted_application,
265       },
266       creator: PersonSafe {
267         id: inserted_sara_person.id,
268         name: inserted_sara_person.name.to_owned(),
269         display_name: None,
270         published: inserted_sara_person.published,
271         avatar: None,
272         actor_id: inserted_sara_person.actor_id.to_owned(),
273         local: true,
274         banned: false,
275         ban_expires: None,
276         deleted: false,
277         admin: false,
278         bot_account: false,
279         bio: None,
280         banner: None,
281         updated: None,
282         inbox_url: inserted_sara_person.inbox_url.to_owned(),
283         shared_inbox_url: None,
284         matrix_user_id: None,
285       },
286       admin: None,
287     };
288
289     assert_eq!(read_sara_app_view, expected_sara_app_view);
290
291     // Do a batch read of the applications
292     let apps = RegistrationApplicationQuery::builder()
293       .conn(conn)
294       .unread_only(Some(true))
295       .build()
296       .list()
297       .unwrap();
298
299     assert_eq!(
300       apps,
301       [
302         read_jess_app_view.to_owned(),
303         expected_sara_app_view.to_owned()
304       ]
305     );
306
307     // Make sure the counts are correct
308     let unread_count = RegistrationApplicationView::get_unread_count(conn, false).unwrap();
309     assert_eq!(unread_count, 2);
310
311     // Approve the application
312     let approve_form = RegistrationApplicationForm {
313       admin_id: Some(inserted_timmy_person.id),
314       deny_reason: None,
315       ..RegistrationApplicationForm::default()
316     };
317
318     RegistrationApplication::update(conn, sara_app.id, &approve_form).unwrap();
319
320     // Update the local_user row
321     let approve_local_user_form = LocalUserForm {
322       accepted_application: Some(true),
323       ..LocalUserForm::default()
324     };
325
326     LocalUser::update(conn, inserted_sara_local_user.id, &approve_local_user_form).unwrap();
327
328     let read_sara_app_view_after_approve =
329       RegistrationApplicationView::read(conn, sara_app.id).unwrap();
330
331     // Make sure the columns changed
332     expected_sara_app_view
333       .creator_local_user
334       .accepted_application = true;
335     expected_sara_app_view.registration_application.admin_id = Some(inserted_timmy_person.id);
336
337     expected_sara_app_view.admin = Some(PersonSafe {
338       id: inserted_timmy_person.id,
339       name: inserted_timmy_person.name.to_owned(),
340       display_name: None,
341       published: inserted_timmy_person.published,
342       avatar: None,
343       actor_id: inserted_timmy_person.actor_id.to_owned(),
344       local: true,
345       banned: false,
346       ban_expires: None,
347       deleted: false,
348       admin: true,
349       bot_account: false,
350       bio: None,
351       banner: None,
352       updated: None,
353       inbox_url: inserted_timmy_person.inbox_url.to_owned(),
354       shared_inbox_url: None,
355       matrix_user_id: None,
356     });
357     assert_eq!(read_sara_app_view_after_approve, expected_sara_app_view);
358
359     // Do a batch read of apps again
360     // It should show only jessicas which is unresolved
361     let apps_after_resolve = RegistrationApplicationQuery::builder()
362       .conn(conn)
363       .unread_only(Some(true))
364       .build()
365       .list()
366       .unwrap();
367     assert_eq!(apps_after_resolve, vec![read_jess_app_view]);
368
369     // Make sure the counts are correct
370     let unread_count_after_approve =
371       RegistrationApplicationView::get_unread_count(conn, false).unwrap();
372     assert_eq!(unread_count_after_approve, 1);
373
374     // Make sure the not undenied_only has all the apps
375     let all_apps = RegistrationApplicationQuery::builder()
376       .conn(conn)
377       .build()
378       .list()
379       .unwrap();
380     assert_eq!(all_apps.len(), 2);
381
382     Person::delete(conn, inserted_timmy_person.id).unwrap();
383     Person::delete(conn, inserted_sara_person.id).unwrap();
384     Person::delete(conn, inserted_jess_person.id).unwrap();
385   }
386 }