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,
|
||||
},
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ReadingEvent {
|
||||
MaterialOpened {
|
||||
@ -30,3 +30,81 @@ pub enum ReadingEvent {
|
||||
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