thot-local 0.10.0-intermediate

Local functionality for Thot data management and analysis software.
Documentation
//! # Note
//! There are concurrency errors that cause tests to fail.
//! To ensure a test is failing run it singularly.
use super::*;
use crate::system::collections::users::Users;
use crate::result::Error;
use crate::system::resources::user::User;
use fake::faker::internet::raw::FreeEmail;
use fake::faker::name::raw::Name;
use fake::locales::EN;
use fake::Fake;
use settings_manager::prelude::ListSetting;
// use settings_manager_change_path::settings_path;

// *************
// *** tests ***
// *************

#[test]
fn user_by_email_should_work() {
    // add new user
    let user = create_user();
    add_user(user.clone()).expect("should not error");

    let found = match user_by_email(&user.email) {
        Ok(u) => u,
        Err(err) => panic!("should not error: {:?}", err),
    };

    assert_eq!(user.rid, found.rid, "user ids do not match");
}

#[test]
fn user_by_email_should_error_if_user_does_not_exist() {
    let email: String = FreeEmail(EN).fake();
    match user_by_email(&email) {
        Ok(u) => assert!(
            false,
            "found user with different email: given {}, found {}",
            email, u.email
        ),
        Err(Error::ResourceError(ResourceError::DoesNotExist(_))) => {} // correct
        Err(err) => assert!(false, "incorrect error: {:?}", err),
    }
}

#[test]
//#[settings_path("")]
fn add_user_should_work() {
    // add new user
    let user = create_user();
    add_user(user.clone()).expect("should not error");

    // get current users
    let mut users = Users::load().expect("users list should load");
    let matches: Vec<&User> = users
        .items()
        .iter()
        .filter(|u| u.rid == user.rid)
        .collect();

    assert_ne!(0, matches.len(), "user was not added to settings");
    assert_eq!(1, matches.len(), "user has non-unique id");
}

#[test]
fn add_user_should_error_if_email_exists() {
    let email: String = FreeEmail(EN).fake();
    let email0 = email.clone();
    let email1 = email.clone();

    let name0: String = Name(EN).fake();
    let name1: String = Name(EN).fake();

    let user0 = User::new(email0, Some(name0));
    let user1 = User::new(email1, Some(name1));

    // add first user
    add_user(user0).expect("should not error");

    // add second user
    match add_user(user1) {
        Ok(_) => {
            assert!(false, "should not succeed: {}", email)
        }

        Err(Error::UsersError(UsersError::DuplicateEmail(_))) => {} // pass

        Err(err) => {
            assert!(false, "unexpected error kind: {:?}", err)
        }
    };
}

#[test]
fn add_user_should_error_if_email_is_invalid() {
    let name: String = Name(EN).fake();
    let email = String::from("invalid");

    let user = User::new(email, Some(name));
    match add_user(user) {
        Ok(_) => {
            assert!(false, "should not succeed")
        }

        Err(Error::UsersError(UsersError::InvalidEmail(_))) => {} // pass

        Err(err) => {
            assert!(false, "unexpected error kind: {:?}", err)
        }
    };
}

#[test]
fn delete_user_should_remove_an_existing_user() {
    // add and remove user
    let user = create_user();
    let user_id = user.rid.clone();

    add_user(user).expect("add user should not error");
    delete_user(&user_id).expect("delete user should not error");

    // check user is not in settings
    let mut users = Users::load().expect("users list should load");
    let user_match: Vec<User> = users
        .items()
        .clone()
        .into_iter()
        .filter(|u| u.rid == user_id)
        .collect();

    assert_eq!(0, user_match.len(), "user was not deleted");
}

#[test]
fn delete_user_should_exit_silently_if_user_did_not_exist() {
    let user = create_user();
    delete_user(&user.rid).expect("delete user should not error");

    assert_eq!(
        true, true,
        "deleting non-existant user did not exit silently"
    );
}

#[test]
fn delete_user_should_unset_as_active_user() {
    let user = create_user();
    let user_id = user.rid.clone();

    add_user(user).expect("add user should not error");
    set_active_user(&user_id).expect("set active user should work");
    delete_user(&user_id).expect("delete user should not error");

    let settings = UserSettings::load().expect("could not load settings");
    assert_eq!(None, settings.active_user, "active user should not be set");

    drop(settings);
    delete_user(&user_id).expect("delete user should not error");
}

#[test]
fn delete_user_by_email_should_remove_an_existing_user() {
    // add and remove user
    let user = create_user();
    let user_email = user.email.clone();
    let user_id = user.rid.clone();

    add_user(user).expect("add user should not error");
    delete_user_by_email(&user_email).expect("delete user should not error");

    // check user is not in settings
    let mut users = Users::load().expect("users list should load");
    let user_match: Vec<User> = users
        .items()
        .clone()
        .into_iter()
        .filter(|u| u.rid == user_id)
        .collect();

    assert_eq!(0, user_match.len(), "user was not deleted");
}

#[test]
fn delete_user_by_email_should_exit_silently_if_user_did_not_exist() {
    let user = create_user();
    delete_user_by_email(&user.email).expect("delete user should not error");
}

#[test]
fn delete_user_by_email_should_unset_as_active_user() {
    let user = create_user();
    let user_id = user.rid.clone();
    let email = user.email.clone();

    add_user(user).expect("add user should not error");
    set_active_user(&user_id).expect("set active user should work");
    delete_user_by_email(&email).expect("delete user should not error");

    let settings = UserSettings::load().expect("could not load settings");
    assert_eq!(None, settings.active_user, "active user should not be set");

    drop(settings);
    delete_user(&user_id).expect("delete user should not error");
}

#[test]
fn update_user_should_work() {
    // setup
    let user = create_user();
    let user_id = user.rid.clone();
    add_user(user).expect("add user should not error");

    // test
    let mut new_user = create_user();
    let new_user_name = new_user.name.clone();
    let new_user_email = new_user.email.clone();

    new_user.rid = user_id.clone();

    update_user(new_user).expect("edit user should not error");

    // check user is not in settings
    let mut users = Users::load().expect("users list should load");
    let user_match: Vec<User> = users
        .items()
        .clone()
        .into_iter()
        .filter(|u| u.rid == user_id)
        .collect();

    assert_ne!(0, user_match.len(), "user was not added to settings");
    assert_eq!(1, user_match.len(), "multiple users with same id found");

    let edited_user = &user_match[0];
    assert_eq!(new_user_name, edited_user.name, "name was not edited");
    assert_eq!(new_user_email, edited_user.email, "email was not edited");

    // clean up
    drop(users); // free settings so delete_user can run
    delete_user(&user_id).expect("delete user should not error");
}

#[test]
fn update_user_should_error_if_user_does_not_exist() {
    let user = create_user();
    match update_user(user) {
        Ok(_) => {
            assert!(false, "should not succeed")
        }

        Err(Error::ResourceError(ResourceError::DoesNotExist(_))) => {} // pass

        Err(err) => {
            assert!(false, "unexpected error kind: {:?}", err)
        }
    }
}

#[test]
fn update_user_should_error_if_email_is_invalid() {
    // setup
    let user = create_user();
    let mut edited_user = user.clone();
    add_user(user).expect("add user should not error");

    // test
    edited_user.email = String::from("invalid_email");
    match update_user(edited_user) {
        Ok(_) => {
            assert!(false, "should not succeed")
        }

        Err(Error::UsersError(UsersError::InvalidEmail(_))) => {} // pass

        Err(err) => {
            assert!(false, "unexpected error kind: {:?}", err)
        }
    };
}

#[test]
fn set_active_user_should_work() {
    // setup
    let user = create_user();
    add_user(user.clone()).expect("add user should not error");
    set_active_user(&user.rid).expect("set active user should not error");
    let settings = UserSettings::load().expect("could not load settings");

    // test
    let active_user = settings.active_user.clone();

    assert!(active_user.is_some(), "active user is None");
    let active_user = active_user.unwrap();

    assert_eq!(
        user.rid, active_user,
        "incorrect user is active"
    );

    // clean up
    drop(settings); // free settings so delete_user can run
    delete_user(&user.rid).expect("delete user should not error");
}

#[test]
fn set_active_user_should_error_if_user_does_not_exist() {
    let user = create_user();
    match set_active_user(&user.rid) {
        Ok(_) => assert!(false, "should not succeed"),
        Err(Error::ResourceError(ResourceError::DoesNotExist(_))) => {} // pass
        Err(err) => assert!(false, "unexpected error kind: {:?}", err),
    };
}

#[test]
fn set_active_user_by_email_should_work() {
    // setup
    let user = create_user();
    add_user(user.clone()).expect("add user should not error");
    set_active_user_by_email(&user.email).expect("set active user should not error");
    let settings = UserSettings::load().expect("could not load settings");

    // test
    let active_user = settings.active_user.clone();
    assert!(active_user.is_some(), "active user is None");

    let active_user = active_user.unwrap();

    assert_eq!(
        user.rid, active_user,
        "incorrect user is active"
    );

    // clean up
    drop(settings); // free settings so delete_user can run
    delete_user(&user.rid).expect("delete user should not error");
}

#[test]
fn set_active_user_by_email_should_error_if_user_does_not_exist() {
    let user = create_user();
    match set_active_user_by_email(&user.email) {
        Ok(_) => assert!(false, "should not succeed"),
        Err(Error::ResourceError(ResourceError::DoesNotExist(_))) => {} // pass
        Err(err) => assert!(false, "unexpected error kind: {:?}", err),
    };
}

#[test]
fn unset_active_user_should_work() {
    // setup
    let user = create_user();
    let user_id = user.rid.clone();
    add_user(user).expect("add user should not error");
    set_active_user(&user_id).expect("set active user should not error");

    // test
    unset_active_user().expect("unset active user should not error");

    let settings = UserSettings::load().expect("could not load settings");

    assert!(settings.active_user.is_none(), "active user still set");

    // clean up
    drop(settings); // free settings so delete_user can run

    delete_user(&user_id).expect("delete user should not error");
}

#[test]
fn unset_active_user_should_end_quietly_if_no_user_is_set() {
    unset_active_user().expect("unset active user should not error");

    unset_active_user().expect("unset active user should not error if already unset");

    let settings = UserSettings::load().expect("could not load settings");

    assert!(settings.active_user.is_none(), "active user still set");
}

// *****************
// *** functions ***
// *****************

fn create_user() -> User {
    let name: String = Name(EN).fake();
    let email: String = FreeEmail(EN).fake();

    User::new(email, Some(name))
}