libwebnovel-storage 0.3.2

A complement to libwebnovel: this package handles downloading and organizing collections of followed webnovels
Documentation
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

use libwebnovel_storage::{LibraryError, LocalLibrary};
use log::{debug, info};
use tempfile::{tempdir, TempDir};
use test_log::test;
use url::Url;

fn get_library() -> (TempDir, LocalLibrary, PathBuf, PathBuf) {
    let dir = tempdir().unwrap();
    let config_dir = dir.path().join("libwnvl-storage").join("config");
    let config_file_path = config_dir.join("config.toml");
    let data_dir = dir.path().join("libwnvl-storage").join("data");
    let library = LocalLibrary::load(&config_file_path).unwrap();
    debug!("{:#?}", &library);
    (dir, library, config_file_path, data_dir)
}
fn read_file(path: &Path) -> Result<String, std::io::Error> {
    let mut f = File::open(path)?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
}

#[test]
fn test_config_file_creation() {
    let (_dir, mut library, config_file_path, data_dir) = get_library();
    library.persist().unwrap();
    assert!(config_file_path.exists());
    let s = read_file(&config_file_path).unwrap();
    debug!("config file content:\n{}", s);
    info!(
        "Moving library base dir from {} to {}",
        library.base_path().display(),
        data_dir.display()
    );
    library.set_base_path(&data_dir).unwrap();
    debug!("{:#?}", &library);
    library.persist().unwrap();
    assert!(config_file_path.exists());
    let mut f = File::open(&config_file_path).unwrap();
    let mut s = String::new();
    f.read_to_string(&mut s).unwrap();
    debug!("config file content:\n{}", s);
    assert_eq!(library.base_path(), data_dir);
}

#[test]
fn test_webnovel_adding() {
    let (_dir, mut library, config_file_path, data_dir) = get_library();
    library.set_base_path(data_dir).unwrap();
    let novel_url = "https://www.royalroad.com/fiction/73475/chasing-sunlight";
    library.add(novel_url).unwrap();
    debug!("{:#?}", &library);
    assert_eq!(library.novels()[0].url().to_string(), novel_url);
    assert_eq!(library.novels()[0].get_remote_chapter_count().unwrap(), 30);
    assert_eq!(library.novels()[0].get_local_chapter_count().unwrap(), 0);
    library.persist().unwrap();
    let s = read_file(&config_file_path).unwrap();
    debug!("{}", s);
    library.update().unwrap();
    assert_eq!(library.novels()[0].get_remote_chapter_count().unwrap(), 30);
    assert_eq!(library.novels()[0].get_local_chapter_count().unwrap(), 30);
}

#[test]
fn test_webnovel_overwrite() -> Result<(), Box<dyn std::error::Error>> {
    let (_dir, mut library, _config_file_path, data_dir) = get_library();
    library.set_base_path(data_dir)?;
    library.add("https://www.royalroad.com/fiction/73475/chasing-sunlight")?;
    let _results = library.update();
    match library.add("https://www.royalroad.com/fiction/73475/chasing-sunlight") {
        Ok(_) => panic!("we should have recieved an error when adding again the same URL."),
        Err(e) => {
            match e {
                LibraryError::NovelAlreadyPresent(url) => {
                    assert_eq!(url, Url::parse("https://www.royalroad.com/fiction/73475/chasing-sunlight").unwrap());
                },
                _ => panic!("We should have recieved a NovelAlreadyPresent error when adding again same URL, but got {e}")
            }
        }
    }

    Ok(())
}
#[test]
fn test_webnovel_cover() -> Result<(), Box<dyn std::error::Error>> {
    let (_dir, mut library, _config_file_path, data_dir) = get_library();
    library.set_base_path(data_dir)?;
    library.add("https://www.royalroad.com/fiction/73475/chasing-sunlight")?;
    for library in library.novels() {
        library.download_cover()?;
    }
    Ok(())
}

#[test]
fn test_chapter_update() {
    let (_dir, mut library, _config_file_path, data_dir) = get_library();
    library.set_base_path(data_dir).unwrap();
    library
        .add("https://www.royalroad.com/fiction/73475/chasing-sunlight")
        .unwrap();
    let novels = library.novels_mut();
    for novel in novels.iter_mut() {
        assert_eq!(novel.get_local_chapter_count().unwrap(), 0);
        assert_eq!(novel.get_remote_chapter_count().unwrap(), 30);
        assert_eq!(novel.get_missing_chapters_indexes().unwrap().len(), 30);
        novel.update().unwrap();
        assert_eq!(novel.get_local_chapter_count().unwrap(), 30);
        assert_eq!(novel.get_remote_chapter_count().unwrap(), 30);
        assert_eq!(novel.get_missing_chapters_indexes().unwrap().len(), 0);
        novel.update().unwrap();
        assert_eq!(novel.get_local_chapter_count().unwrap(), 30);
        assert_eq!(novel.get_remote_chapter_count().unwrap(), 30);
        assert_eq!(novel.get_missing_chapters_indexes().unwrap().len(), 0);
    }
}