Removing api tests form members mod as those are done with curl in tests/

Base member creation being added in this commit notes to follow

struct Member has had its field types changed to db_types::* types
Member::to_json was added to support simple json serialization into responses
struct InsertableMember added because `id` is generated by SQL for us
- this means we have to do two queries 1 to insert and 2 to fetch
- mysql_async does not provide an inlined way of fetching a recently added row

func general_new_user is only checking for a `name`parameter
- falls back to a basic default name for those that don't set a name on jooin
- handles its  own sub errors so the main dispatcher doesn't care about after move
This commit is contained in:
shockrah 2020-07-13 21:59:28 -07:00
parent 46403913a4
commit 99507302f9

View File

@ -1,48 +1,97 @@
use mysql_async::{Pool, Conn};
use crate::badges::Badge;
use crate::err::DbError;
use chrono::Utc;
use hyper::{Body, Response, StatusCode};
use hyper::header::{HeaderName, HeaderValue};
use mysql_async::{Conn, Pool};
use mysql_async::prelude::{params, Queryable};
use mysql_async::error::Error as SQLError;
use serde_json::Value;
use crate::db_types::{UBigInt, BigInt, Integer, VarChar};
pub struct Member {
id: u64,
name: String,
permissions: u64,
badges: Option<Vec<Badge>>,
id: UBigInt,
secret: VarChar,
name: VarChar,
joindate: BigInt,
status: Integer,
permissions: UBigInt,
}
impl Member {
pub fn to_json(&self) -> String {
unimplemented!()
}
}
struct InsertableMember<'n> {
name: &'n str,
permissions: u64,
badges: Option<Vec<Badge>>
}
impl<'n> InsertableMember<'n> {
fn new(name: &'n str) -> InsertableMember<'n> {
use crate::perms::{JOIN_VOICE, SEND_MESSAGES};
async fn insert_new_member<'nm>(conn: &Conn, name: &'nm str)
-> Result<Member, DbError<'nm>> {
// Updates both the members and keys table accordingly
use crate::perms::{JOIN_VOICE, SEND_MESSAGES};
let m = InsertableMember {
name: name,
permissions: JOIN_VOICE | SEND_MESSAGES, // can join voice and send messages by default
badges: None
};
// TODO: this stuff once the invites/ user generation to be done
// conn.batch_exec(
// r"INSERT INTO `members` (name, status)",
// params!{
// "name" => name,
// "join"
// }
// ).await;
Err(DbError::from("Could not create user"))
}
#[cfg(test)]
mod members_tests {
use mysql_async::{Pool, Conn};
use std::env::var;
use dotenv::dotenv;
#[test]
fn db_create_member() {
let conn = Pool::new(&var("DATABASE_URL").unwrap()).get_conn();
let now: BigInt = Utc::now().timestamp_millis();
let default_perms = JOIN_VOICE | SEND_MESSAGES;
InsertableMember {
name: name,
permissions: default_perms,
}
}
}
}
async fn insert_new_member<'nm>(conn: Conn, mem: InsertableMember<'nm>)
-> Result<Member, SQLError> {
// standard insertion with no checks, those should be done before we get here
// in theory only 500's should happen here assuming we did everything else right
let conn = conn.batch_exec(
"INSERT INTO `members` () ",
mysql_async::params!{
"name" => mem.name,
"permissions" => mem.permissions,
/*"badges" => mem.permissions*/ // not used yet as we have no serializer
}).await?;
type MemberRow = (UBigInt, VarChar, VarChar, BigInt, Integer, UBigInt);
let (conn, row): (Conn, Option<MemberRow>) = conn.first_exec(
"SELECT * from `members` WHERE `secret` = :secret ",
params!{
"secret" => mem.name
}).await?;
Ok(Member {
id: 0,
secret: "secret".into(),
name: "String".into(),
joindate: 123,
status: 69,
permissions: 0,
})
}
async fn general_new_user(p: &Pool, resp: &mut Response<Body>, params: Value) {
/*
* @name: string => desired default name
*/
let default_name = serde_json::json!("NewUser");
let name = params.get("name")
.unwrap_or(&default_name)
.as_str().unwrap_or("NewUser");
let pre_mem = InsertableMember::new(name);
if let Ok(conn) = p.get_conn().await {
match insert_new_member(conn, pre_mem).await {
Ok(new_member) => {
*resp.status_mut() = StatusCode::OK;
let json_hdr_name = HeaderName::from_static("Content-Type");
let json_hdr_val = HeaderValue::from_static("application/json");
resp.headers_mut().insert(json_hdr_name, json_hdr_val);
*resp.body_mut() = Body::from(new_member.to_json());
},
Err(_) => {
*resp.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
*resp.body_mut() = Body::from("Could not process input");
}
}
}
}