forked from lavina/lavina
1
0
Fork 0
lavina/crates/projection-irc/tests/lib.rs

93 lines
3.2 KiB
Rust

use std::time::Duration;
use anyhow::Result;
use lavina_core::repo::{Storage, StorageConfig};
use lavina_core::{player::PlayerRegistry, room::RoomRegistry};
use projection_irc::{launch, read_irc_message, ServerConfig};
use prometheus::Registry as MetricsRegistry;
use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::net::tcp::{ReadHalf, WriteHalf};
use tokio::net::TcpStream;
struct TestScope<'a> {
reader: BufReader<ReadHalf<'a>>,
writer: WriteHalf<'a>,
buffer: Vec<u8>,
pub timeout: Duration,
}
impl<'a> TestScope<'a> {
fn new(stream: &mut TcpStream) -> TestScope<'_> {
let (reader, writer) = stream.split();
let reader = BufReader::new(reader);
TestScope {
reader,
writer,
buffer: vec![],
timeout: Duration::from_millis(100),
}
}
async fn send(&mut self, str: &(impl AsRef<str> + ?Sized)) -> Result<()> {
self.writer.write_all(str.as_ref().as_bytes()).await?;
self.writer.write_all(b"\r\n").await?;
self.writer.flush().await?;
Ok(())
}
async fn expect(&mut self, str: &str) -> Result<()> {
let len = tokio::time::timeout(self.timeout, read_irc_message(&mut self.reader, &mut self.buffer)).await??;
assert_eq!(std::str::from_utf8(&self.buffer[..len - 2])?, str);
self.buffer.clear();
Ok(())
}
async fn assert(&mut self, f: impl FnOnce(&str) -> Result<()>) -> Result<()> {
let len = tokio::time::timeout(self.timeout, read_irc_message(&mut self.reader, &mut self.buffer)).await??;
let res = f(std::str::from_utf8(&self.buffer[..len - 2])?);
self.buffer.clear();
res
}
}
#[tokio::test]
async fn scenario_basic() -> Result<()> {
let config = ServerConfig {
listen_on: "127.0.0.1:0".parse().unwrap(),
server_name: "testserver".into(),
};
let mut metrics = MetricsRegistry::new();
let mut storage = Storage::open(StorageConfig {
db_path: ":memory:".into(),
})
.await?;
let rooms = RoomRegistry::new(&mut metrics, storage.clone()).unwrap();
let players = PlayerRegistry::empty(rooms.clone(), &mut metrics).unwrap();
let server = launch(config, players, rooms, metrics, storage.clone()).await.unwrap();
// test scenario
storage.create_user("tester").await?;
storage.set_password("tester", "password").await?;
let mut stream = TcpStream::connect(server.addr).await?;
let mut s = TestScope::new(&mut stream);
s.expect(":testserver NOTICE * :Welcome to my server!").await?;
s.send("PASS password").await?;
s.send("NICK tester").await?;
s.send("USER UserName 0 * :Real Name").await?;
s.expect(":testserver 001 tester :Welcome to Kek Server").await?;
s.expect(":testserver 002 tester :Welcome to Kek Server").await?;
s.expect(":testserver 003 tester :Welcome to Kek Server").await?;
s.expect(":testserver 004 tester testserver kek-0.1.alpha.3 r CFILPQbcefgijklmnopqrstvz").await?;
s.expect(":testserver 005 tester CHANTYPES=# :are supported by this server").await?;
stream.shutdown().await?;
// wrap up
server.terminate().await.unwrap();
Ok(())
}