use crate::{ Result, AdapterPool, db::{ Channel, ChannelId, Feed, FeedId, Item, }, }; pub struct UnparsedFeedChannel { pub channel_id: i64, pub feed_id: i64, } impl UnparsedFeedChannel { pub fn parse(self) -> Result { Ok(FeedChannel { channel_id: ChannelId(self.channel_id), feed_id: FeedId(self.feed_id) }) } } pub struct FeedChannel { channel_id: ChannelId, feed_id: FeedId, } impl FeedChannel { pub async fn get_channel(&self, pool: &AdapterPool) -> Result { Channel::get(pool, self.channel_id).await } pub async fn get_feed(&self, pool: &AdapterPool) -> Result { Feed::get(pool, self.feed_id).await } pub async fn add_item( &self, pool: &AdapterPool, item: &Item ) -> Result<()> { let int_item_id = i64::from(item.id()); let int_feed_id = i64::from(self.feed_id); sqlx::query!( "INSERT OR IGNORE INTO feed_items (feed_id, item_id, score) VALUES (?, ?, 5)", // TODO: Add in scoring featuress int_feed_id, int_item_id ).execute(&pool.0).await?; Ok(()) } } #[cfg(test)] mod tests { use super::*; use reqwest::Url; use crate::{ Adapter, AdapterBuilder, db::{ Channel, FeedId, User } }; const FEED1: &str = "https://example.com/feed"; async fn setup_adapter() -> Adapter { AdapterBuilder::new() .database_url("sqlite::memory:") .create().await.unwrap() } // FeedChannel Tests #[tokio::test] async fn get_channel() { let adapter = setup_adapter().await; let pool = adapter.get_pool(); let url = Url::parse(FEED1).unwrap(); let channel = Channel::get_or_create(pool, url).await.unwrap(); let fc = FeedChannel { channel_id: channel.id(), feed_id: FeedId(1), // Fake Feed }; let channel_from_fc = fc.get_channel(pool).await.unwrap(); assert_eq!(channel_from_fc.id(), channel.id()); } #[tokio::test] async fn get_feed() { let adapter = setup_adapter().await; let pool = adapter.get_pool(); let user = User::create(pool, "Alice").await.unwrap(); let feed = Feed::create(pool, user.id(), "My Feed").await.unwrap(); let fc = FeedChannel { channel_id: ChannelId(1), // Fake Channel feed_id: feed.id(), }; let feed_from_fc = fc.get_feed(pool).await.unwrap(); assert_eq!(feed_from_fc.id(), feed.id()); } #[tokio::test] pub async fn add_item() { let adapter = setup_adapter().await; let pool = adapter.get_pool(); let user = User::create(pool, "Alice").await.unwrap(); let feed = Feed::create(pool, user.id(), "My Feed").await.unwrap(); let url = Url::parse(FEED1).unwrap(); let channel = Channel::get_or_create(pool, url).await.unwrap(); let fc = FeedChannel { channel_id: channel.id(), feed_id: feed.id(), }; let item = Item::get_or_create(pool, channel.id(), "item-guid").await.unwrap(); fc.add_item(pool, &item).await.unwrap(); let items = feed.get_items(pool, 1, 0).await.unwrap(); assert_eq!(items[0].id(), item.id()); } }