feat: ReadingEvent serde tests + NoteAnchor with from_position constructor and tests
This commit is contained in:
parent
b3a7fe0414
commit
b5f8e273a9
@ -29,3 +29,82 @@ pub enum NoteAnchor {
|
|||||||
knowledge_item_id: String,
|
knowledge_item_id: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl NoteAnchor {
|
||||||
|
/// Create a NoteAnchor from a material_id and optional ReadingPosition.
|
||||||
|
pub fn from_position(material_id: &str, position: Option<&crate::progress::ReadingPosition>) -> Self {
|
||||||
|
match position {
|
||||||
|
Some(crate::progress::ReadingPosition::Markdown { block_id, .. }) => {
|
||||||
|
NoteAnchor::MarkdownBlock {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
block_id: block_id.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(crate::progress::ReadingPosition::Text { line_number, .. }) => {
|
||||||
|
NoteAnchor::TextLine {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
line_number: *line_number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(crate::progress::ReadingPosition::Pdf { page_number, .. }) => {
|
||||||
|
NoteAnchor::PdfPage {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
page_number: *page_number,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(crate::progress::ReadingPosition::Image { .. }) => NoteAnchor::Image {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
},
|
||||||
|
Some(crate::progress::ReadingPosition::Epub { chapter_id, .. }) => {
|
||||||
|
NoteAnchor::EpubChapter {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
chapter_id: chapter_id.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => NoteAnchor::Material {
|
||||||
|
material_id: material_id.to_string(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::progress::ReadingPosition;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_material_anchor() {
|
||||||
|
let a = NoteAnchor::from_position("abc", None);
|
||||||
|
assert_eq!(a, NoteAnchor::Material { material_id: "abc".into() });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_markdown_anchor() {
|
||||||
|
let pos = ReadingPosition::Markdown { block_id: "h1".into(), scroll_progress: 0.5 };
|
||||||
|
let a = NoteAnchor::from_position("abc", Some(&pos));
|
||||||
|
assert_eq!(a, NoteAnchor::MarkdownBlock { material_id: "abc".into(), block_id: "h1".into() });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_pdf_anchor() {
|
||||||
|
let pos = ReadingPosition::Pdf { page_number: 3, page_progress: 0.5, overall_progress: 0.1 };
|
||||||
|
let a = NoteAnchor::from_position("abc", Some(&pos));
|
||||||
|
assert_eq!(a, NoteAnchor::PdfPage { material_id: "abc".into(), page_number: 3 });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_anchor_serde() {
|
||||||
|
let a = NoteAnchor::MarkdownBlock { material_id: "abc".into(), block_id: "h1".into() };
|
||||||
|
let json = serde_json::to_string(&a).unwrap();
|
||||||
|
let back: NoteAnchor = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unknown_position_falls_back_to_material() {
|
||||||
|
let pos = ReadingPosition::Unknown;
|
||||||
|
let a = NoteAnchor::from_position("abc", Some(&pos));
|
||||||
|
assert_eq!(a, NoteAnchor::Material { material_id: "abc".into() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::progress::ReadingPosition;
|
use crate::progress::ReadingPosition;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ReadingEvent {
|
pub enum ReadingEvent {
|
||||||
MaterialOpened {
|
MaterialOpened {
|
||||||
@ -30,3 +30,81 @@ pub enum ReadingEvent {
|
|||||||
timestamp_ms: i64,
|
timestamp_ms: i64,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_material_opened_serde() {
|
||||||
|
let e = ReadingEvent::MaterialOpened {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
timestamp_ms: 1000,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
assert!(json.contains("\"type\":\"MaterialOpened\""));
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_material_closed_serde() {
|
||||||
|
let e = ReadingEvent::MaterialClosed {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
timestamp_ms: 2000,
|
||||||
|
active_seconds: 120,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_position_changed_serde() {
|
||||||
|
let e = ReadingEvent::PositionChanged {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
position: ReadingPosition::Markdown { block_id: "h1".into(), scroll_progress: 0.5 },
|
||||||
|
timestamp_ms: 3000,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_heartbeat_serde() {
|
||||||
|
let e = ReadingEvent::Heartbeat {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
active_seconds: 15,
|
||||||
|
position: None,
|
||||||
|
timestamp_ms: 4000,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_heartbeat_with_position_serde() {
|
||||||
|
let e = ReadingEvent::Heartbeat {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
active_seconds: 15,
|
||||||
|
position: Some(ReadingPosition::Pdf { page_number: 3, page_progress: 0.5, overall_progress: 0.1 }),
|
||||||
|
timestamp_ms: 5000,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_marked_as_read_serde() {
|
||||||
|
let e = ReadingEvent::MarkedAsRead {
|
||||||
|
material_id: "abc".into(),
|
||||||
|
timestamp_ms: 6000,
|
||||||
|
};
|
||||||
|
let json = serde_json::to_string(&e).unwrap();
|
||||||
|
let back: ReadingEvent = serde_json::from_str(&json).unwrap();
|
||||||
|
assert_eq!(back, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user