#![cfg(test)] use diesel::prelude::*; use uuid::Uuid; use crate::models::feed::new_feed::NewFeed; use crate::models::feed::rss_feed::Feed; use crate::models::feed_item::new_feed_item::NewFeedItem; use crate::models::feed_item::rss_feed_item::FeedItem; use crate::models::user::new_user::NewUser; use crate::models::user::rss_user::User; use crate::schema::{feed, feed_item, users}; // Test fixtures are written through the same models/schema as the app and // cleaned up explicitly afterwards (rather than wrapped in a rolled-back // transaction), because every handler opens its own DB connection via // `establish_connection`, so a transaction held by the test would not be // visible to the handler under test. Random suffixes keep parallel test runs // from colliding on the unique username/email/url constraints. pub fn unique_suffix() -> String { Uuid::new_v4().to_string() } pub fn insert_user(connection: &mut PgConnection, password: &str) -> User { let suffix = unique_suffix(); let new_user = NewUser::new( format!("test_user_{suffix}"), format!("test_{suffix}@example.test"), password.to_string(), ); diesel::insert_into(users::table) .values(&new_user) .get_result(connection) .expect("failed to insert test user") } pub fn delete_user(connection: &mut PgConnection, user_id: i32) { diesel::delete(users::table.filter(users::id.eq(user_id))) .execute(connection) .ok(); } pub fn insert_feed(connection: &mut PgConnection, owner_id: i32) -> Feed { let suffix = unique_suffix(); let new_feed = NewFeed::new( format!("Test feed {suffix}"), format!("https://example.test/feed/{suffix}"), owner_id, ); diesel::insert_into(feed::table) .values(&new_feed) .get_result(connection) .expect("failed to insert test feed") } pub fn delete_feed(connection: &mut PgConnection, id: i32) { diesel::delete(feed::table.filter(feed::id.eq(id))) .execute(connection) .ok(); } pub fn insert_feed_item(connection: &mut PgConnection, owning_feed_id: i32, read: bool) -> FeedItem { let suffix = unique_suffix(); let new_item = NewFeedItem::new( owning_feed_id, format!("Content {suffix}"), format!("Title {suffix}"), format!("https://example.test/article/{suffix}"), None, ); let item: FeedItem = diesel::insert_into(feed_item::table) .values(&new_item) .get_result(connection) .expect("failed to insert test feed item"); if read { diesel::update(&item) .set(feed_item::read.eq(true)) .execute(connection) .expect("failed to mark test feed item as read"); } item } pub fn delete_feed_item(connection: &mut PgConnection, id: i32) { diesel::delete(feed_item::table.filter(feed_item::id.eq(id))) .execute(connection) .ok(); }