mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 18:31:10 +00:00
tests are running with temp db
This commit is contained in:
parent
9ca2558b06
commit
7c789a1c06
11 changed files with 280 additions and 113 deletions
85
Cargo.lock
generated
85
Cargo.lock
generated
|
@ -529,6 +529,17 @@ dependencies = [
|
||||||
"syn 2.0.39",
|
"syn 2.0.39",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diesel_migrations"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6036b3f0120c5961381b570ee20a02432d7e2d27ea60de9578799cf9156914ac"
|
||||||
|
dependencies = [
|
||||||
|
"diesel",
|
||||||
|
"migrations_internals",
|
||||||
|
"migrations_macros",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "diesel_table_macro_syntax"
|
name = "diesel_table_macro_syntax"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -669,6 +680,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-derive-newtype",
|
"diesel-derive-newtype",
|
||||||
|
"diesel_migrations",
|
||||||
"diffy",
|
"diffy",
|
||||||
"enum_delegate",
|
"enum_delegate",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
|
@ -1194,6 +1206,27 @@ dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "migrations_internals"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f23f71580015254b020e856feac3df5878c2c7a8812297edd6c0a485ac9dada"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "migrations_macros"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cce3325ac70e67bbab5bd837a31cae01f1a6db64e0e744a33cb03a543469ef08"
|
||||||
|
dependencies = [
|
||||||
|
"migrations_internals",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mime"
|
name = "mime"
|
||||||
version = "0.3.17"
|
version = "0.3.17"
|
||||||
|
@ -1810,6 +1843,15 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -2100,6 +2142,40 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.7.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.19.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap 2.1.0",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.4.13"
|
version = "0.4.13"
|
||||||
|
@ -2467,6 +2543,15 @@ version = "0.48.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.5.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.50.0"
|
version = "0.50.0"
|
||||||
|
|
|
@ -12,6 +12,7 @@ axum-macros = "0.3.8"
|
||||||
chrono = { version = "0.4.31", features = ["serde"] }
|
chrono = { version = "0.4.31", features = ["serde"] }
|
||||||
diesel = {version = "2.1.4", features = ["postgres"] }
|
diesel = {version = "2.1.4", features = ["postgres"] }
|
||||||
diesel-derive-newtype = "2.1.0"
|
diesel-derive-newtype = "2.1.0"
|
||||||
|
diesel_migrations = "2.1.0"
|
||||||
diffy = "0.3.0"
|
diffy = "0.3.0"
|
||||||
enum_delegate = "0.2.0"
|
enum_delegate = "0.2.0"
|
||||||
env_logger = { version = "0.10.1", default-features = false }
|
env_logger = { version = "0.10.1", default-features = false }
|
||||||
|
|
|
@ -2,7 +2,7 @@ create table article (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
title text not null,
|
title text not null,
|
||||||
text text not null,
|
text text not null,
|
||||||
ap_id varchar(255) not null,
|
ap_id varchar(255) not null unique,
|
||||||
instance_id varchar(255) not null,
|
instance_id varchar(255) not null,
|
||||||
latest_version text not null,
|
latest_version text not null,
|
||||||
local bool not null
|
local bool not null
|
||||||
|
@ -10,7 +10,7 @@ create table article (
|
||||||
|
|
||||||
create table edit (
|
create table edit (
|
||||||
id serial primary key,
|
id serial primary key,
|
||||||
ap_id varchar(255) not null,
|
ap_id varchar(255) not null unique,
|
||||||
diff text not null,
|
diff text not null,
|
||||||
article_id int REFERENCES article ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
article_id int REFERENCES article ON UPDATE CASCADE ON DELETE CASCADE NOT NULL,
|
||||||
version text not null,
|
version text not null,
|
||||||
|
|
|
@ -45,10 +45,12 @@ async fn create_article(
|
||||||
data: Data<MyDataHandle>,
|
data: Data<MyDataHandle>,
|
||||||
Form(create_article): Form<CreateArticleData>,
|
Form(create_article): Form<CreateArticleData>,
|
||||||
) -> MyResult<Json<DbArticle>> {
|
) -> MyResult<Json<DbArticle>> {
|
||||||
|
dbg!(1);
|
||||||
let existing_article = DbArticle::read_local_title(&create_article.title, &data.db_connection);
|
let existing_article = DbArticle::read_local_title(&create_article.title, &data.db_connection);
|
||||||
if existing_article.is_ok() {
|
if existing_article.is_ok() {
|
||||||
return Err(anyhow!("A local article with this title already exists").into());
|
return Err(anyhow!("A local article with this title already exists").into());
|
||||||
}
|
}
|
||||||
|
dbg!(2);
|
||||||
|
|
||||||
let instance_id = data.local_instance().ap_id;
|
let instance_id = data.local_instance().ap_id;
|
||||||
let ap_id = ObjectId::parse(&format!(
|
let ap_id = ObjectId::parse(&format!(
|
||||||
|
@ -66,9 +68,12 @@ async fn create_article(
|
||||||
instance_id,
|
instance_id,
|
||||||
local: true,
|
local: true,
|
||||||
};
|
};
|
||||||
let article = DbArticle::create(&form, &data.db_connection)?;
|
dbg!(3);
|
||||||
|
let article = dbg!(DbArticle::create(&form, &data.db_connection))?;
|
||||||
|
|
||||||
|
dbg!(4);
|
||||||
CreateArticle::send_to_followers(article.clone(), &data).await?;
|
CreateArticle::send_to_followers(article.clone(), &data).await?;
|
||||||
|
dbg!(5);
|
||||||
|
|
||||||
Ok(Json(article))
|
Ok(Json(article))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::database::{FakeDatabase, MyData, MyDataHandle};
|
use crate::database::FakeDatabase;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::establish_db_connection;
|
|
||||||
use crate::federation::objects::instance::DbInstance;
|
use crate::federation::objects::instance::DbInstance;
|
||||||
use activitypub_federation::config::FederationConfig;
|
|
||||||
use activitypub_federation::fetch::collection_id::CollectionId;
|
use activitypub_federation::fetch::collection_id::CollectionId;
|
||||||
use activitypub_federation::http_signatures::generate_actor_keypair;
|
use activitypub_federation::http_signatures::generate_actor_keypair;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
|
@ -14,7 +12,7 @@ pub mod activities;
|
||||||
pub mod objects;
|
pub mod objects;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
|
||||||
pub async fn federation_config(hostname: &str) -> Result<FederationConfig<MyDataHandle>, Error> {
|
pub async fn create_fake_db(hostname: &str) -> Result<Arc<FakeDatabase>, Error> {
|
||||||
let ap_id = Url::parse(&format!("http://{}", hostname))?;
|
let ap_id = Url::parse(&format!("http://{}", hostname))?;
|
||||||
let articles_id = CollectionId::parse(&format!("http://{}/all_articles", hostname))?;
|
let articles_id = CollectionId::parse(&format!("http://{}/all_articles", hostname))?;
|
||||||
let inbox = Url::parse(&format!("http://{}/inbox", hostname))?;
|
let inbox = Url::parse(&format!("http://{}/inbox", hostname))?;
|
||||||
|
@ -37,16 +35,5 @@ pub async fn federation_config(hostname: &str) -> Result<FederationConfig<MyData
|
||||||
)])),
|
)])),
|
||||||
conflicts: Mutex::new(vec![]),
|
conflicts: Mutex::new(vec![]),
|
||||||
});
|
});
|
||||||
let db_connection = Arc::new(Mutex::new(establish_db_connection()?));
|
Ok(fake_db)
|
||||||
let data = MyData {
|
|
||||||
db_connection,
|
|
||||||
fake_db,
|
|
||||||
};
|
|
||||||
let config = FederationConfig::builder()
|
|
||||||
.domain(hostname)
|
|
||||||
.app_data(data)
|
|
||||||
.debug(true)
|
|
||||||
.build()
|
|
||||||
.await?;
|
|
||||||
Ok(config)
|
|
||||||
}
|
}
|
||||||
|
|
40
src/lib.rs
40
src/lib.rs
|
@ -1,13 +1,18 @@
|
||||||
use crate::api::api_routes;
|
use crate::api::api_routes;
|
||||||
|
use crate::database::MyData;
|
||||||
use crate::error::MyResult;
|
use crate::error::MyResult;
|
||||||
use crate::federation::routes::federation_routes;
|
use crate::federation::routes::federation_routes;
|
||||||
use crate::utils::generate_activity_id;
|
use crate::utils::generate_activity_id;
|
||||||
use activitypub_federation::config::FederationMiddleware;
|
use activitypub_federation::config::{FederationConfig, FederationMiddleware};
|
||||||
use axum::{Router, Server};
|
use axum::{Router, Server};
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use federation::federation_config;
|
use diesel_migrations::embed_migrations;
|
||||||
|
use diesel_migrations::EmbeddedMigrations;
|
||||||
|
use diesel_migrations::MigrationHarness;
|
||||||
|
use federation::create_fake_db;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
@ -16,8 +21,29 @@ pub mod error;
|
||||||
pub mod federation;
|
pub mod federation;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
pub async fn start(hostname: &str) -> MyResult<()> {
|
const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations");
|
||||||
let config = federation_config(hostname).await?;
|
|
||||||
|
pub async fn start(hostname: &str, database_url: &str) -> MyResult<()> {
|
||||||
|
let fake_db = create_fake_db(hostname).await?;
|
||||||
|
|
||||||
|
dbg!(database_url);
|
||||||
|
let db_connection = Arc::new(Mutex::new(PgConnection::establish(database_url)?));
|
||||||
|
db_connection
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.run_pending_migrations(MIGRATIONS)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let data = MyData {
|
||||||
|
db_connection,
|
||||||
|
fake_db,
|
||||||
|
};
|
||||||
|
let config = FederationConfig::builder()
|
||||||
|
.domain(hostname)
|
||||||
|
.app_data(data)
|
||||||
|
.debug(true)
|
||||||
|
.build()
|
||||||
|
.await?;
|
||||||
|
|
||||||
info!("Listening with axum on {hostname}");
|
info!("Listening with axum on {hostname}");
|
||||||
let config = config.clone();
|
let config = config.clone();
|
||||||
|
@ -36,9 +62,3 @@ pub async fn start(hostname: &str) -> MyResult<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn establish_db_connection() -> MyResult<PgConnection> {
|
|
||||||
// TODO: read from config file
|
|
||||||
let database_url = "postgres://fediwiki:password@localhost:5432/fediwiki";
|
|
||||||
Ok(PgConnection::establish(&database_url)?)
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ pub async fn main() -> MyResult<()> {
|
||||||
.filter_module("activitypub_federation", LevelFilter::Info)
|
.filter_module("activitypub_federation", LevelFilter::Info)
|
||||||
.filter_module("fediwiki", LevelFilter::Info)
|
.filter_module("fediwiki", LevelFilter::Info)
|
||||||
.init();
|
.init();
|
||||||
start("localhost:8131").await?;
|
let database_url = "postgres://fediwiki:password@localhost:5432/fediwiki";
|
||||||
|
start("localhost:8131", &database_url).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,8 @@ use once_cell::sync::Lazy;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use serde::de::Deserialize;
|
use serde::de::Deserialize;
|
||||||
use serde::ser::Serialize;
|
use serde::ser::Serialize;
|
||||||
|
use std::env::current_dir;
|
||||||
|
use std::process::{Command, Stdio};
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tracing::log::LevelFilter;
|
use tracing::log::LevelFilter;
|
||||||
|
@ -17,12 +19,9 @@ use url::Url;
|
||||||
pub static CLIENT: Lazy<Client> = Lazy::new(Client::new);
|
pub static CLIENT: Lazy<Client> = Lazy::new(Client::new);
|
||||||
|
|
||||||
pub struct TestData {
|
pub struct TestData {
|
||||||
pub hostname_alpha: &'static str,
|
pub alpha: Instance,
|
||||||
pub hostname_beta: &'static str,
|
pub beta: Instance,
|
||||||
pub hostname_gamma: &'static str,
|
pub gamma: Instance,
|
||||||
handle_alpha: JoinHandle<()>,
|
|
||||||
handle_beta: JoinHandle<()>,
|
|
||||||
handle_gamma: JoinHandle<()>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestData {
|
impl TestData {
|
||||||
|
@ -36,36 +35,61 @@ impl TestData {
|
||||||
.init();
|
.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
let hostname_alpha = "localhost:8131";
|
|
||||||
let hostname_beta = "localhost:8132";
|
|
||||||
let hostname_gamma = "localhost:8133";
|
|
||||||
let handle_alpha = tokio::task::spawn(async {
|
|
||||||
start(hostname_alpha).await.unwrap();
|
|
||||||
});
|
|
||||||
let handle_beta = tokio::task::spawn(async {
|
|
||||||
start(hostname_beta).await.unwrap();
|
|
||||||
});
|
|
||||||
let handle_gamma = tokio::task::spawn(async {
|
|
||||||
start(hostname_gamma).await.unwrap();
|
|
||||||
});
|
|
||||||
Self {
|
Self {
|
||||||
hostname_alpha,
|
alpha: Instance::start("alpha", 8131),
|
||||||
hostname_beta,
|
beta: Instance::start("beta", 8132),
|
||||||
hostname_gamma,
|
gamma: Instance::start("gamma", 8133),
|
||||||
handle_alpha,
|
|
||||||
handle_beta,
|
|
||||||
handle_gamma,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stop(self) -> MyResult<()> {
|
pub fn stop(self) -> MyResult<()> {
|
||||||
self.handle_alpha.abort();
|
self.alpha.stop();
|
||||||
self.handle_beta.abort();
|
self.beta.stop();
|
||||||
self.handle_gamma.abort();
|
self.gamma.stop();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct Instance {
|
||||||
|
db_path: String,
|
||||||
|
pub hostname: String,
|
||||||
|
handle: JoinHandle<()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Instance {
|
||||||
|
fn start(name: &'static str, port: i32) -> Self {
|
||||||
|
let db_path = format!("{}/target/test_db/{name}", current_dir().unwrap().display());
|
||||||
|
// TODO: would be faster to use async Command from tokio and run in parallel
|
||||||
|
Command::new("./tests/scripts/start_dev_db.sh")
|
||||||
|
.arg(&db_path)
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
let db_url = format!("postgresql://lemmy:password@/lemmy?host={db_path}");
|
||||||
|
let hostname = format!("localhost:{port}");
|
||||||
|
let hostname_ = hostname.clone();
|
||||||
|
let handle = tokio::task::spawn(async move {
|
||||||
|
start(&hostname_, &db_url).await.unwrap();
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
db_path,
|
||||||
|
hostname,
|
||||||
|
handle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stop(self) {
|
||||||
|
self.handle.abort();
|
||||||
|
Command::new("./tests/scripts/stop_dev_db.sh")
|
||||||
|
.arg(&self.db_path)
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null())
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const TEST_ARTICLE_DEFAULT_TEXT: &str = "some\nexample\ntext\n";
|
pub const TEST_ARTICLE_DEFAULT_TEXT: &str = "some\nexample\ntext\n";
|
||||||
|
|
||||||
pub async fn create_article(hostname: &str, title: String) -> MyResult<ArticleView> {
|
pub async fn create_article(hostname: &str, title: String) -> MyResult<ArticleView> {
|
||||||
|
|
26
tests/scripts/start_dev_db.sh
Executable file
26
tests/scripts/start_dev_db.sh
Executable file
|
@ -0,0 +1,26 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export PGHOST=$1
|
||||||
|
export PGDATA="$1/dev_pgdata"
|
||||||
|
|
||||||
|
# If cluster exists, stop the server and delete the cluster
|
||||||
|
if [ -d $PGDATA ]
|
||||||
|
then
|
||||||
|
# Prevent `stop` from failing if server already stopped
|
||||||
|
pg_ctl restart > /dev/null
|
||||||
|
pg_ctl stop
|
||||||
|
rm -rf $PGDATA
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create cluster
|
||||||
|
initdb --username=postgres --auth=trust --no-instructions
|
||||||
|
|
||||||
|
#touch "$PGHOST/.s.PGSQL.5432"
|
||||||
|
|
||||||
|
# Start server that only listens to socket in current directory
|
||||||
|
pg_ctl start --options="-c listen_addresses= -c unix_socket_directories=$PGHOST"
|
||||||
|
|
||||||
|
# Setup database
|
||||||
|
psql -c "CREATE USER lemmy WITH PASSWORD 'password' SUPERUSER;" -U postgres
|
||||||
|
psql -c "CREATE DATABASE lemmy WITH OWNER lemmy;" -U postgres
|
9
tests/scripts/stop_dev_db.sh
Executable file
9
tests/scripts/stop_dev_db.sh
Executable file
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export PGHOST=$1
|
||||||
|
export PGDATA="$1/dev_pgdata"
|
||||||
|
echo $PGHOST
|
||||||
|
|
||||||
|
pg_ctl stop
|
||||||
|
rm -rf $PGDATA
|
119
tests/test.rs
119
tests/test.rs
|
@ -24,18 +24,18 @@ async fn test_create_read_and_edit_article() -> MyResult<()> {
|
||||||
|
|
||||||
// create article
|
// create article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
// now article can be read
|
// now article can be read
|
||||||
let get_res = get_article(data.hostname_alpha, create_res.article.id).await?;
|
let get_res = get_article(&data.alpha.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(title, get_res.article.title);
|
assert_eq!(title, get_res.article.title);
|
||||||
assert_eq!(TEST_ARTICLE_DEFAULT_TEXT, get_res.article.text);
|
assert_eq!(TEST_ARTICLE_DEFAULT_TEXT, get_res.article.text);
|
||||||
assert!(get_res.article.local);
|
assert!(get_res.article.local);
|
||||||
|
|
||||||
// error on article which wasnt federated
|
// error on article which wasnt federated
|
||||||
let not_found = get_article(data.hostname_beta, create_res.article.id).await;
|
let not_found = get_article(&data.beta.hostname, create_res.article.id).await;
|
||||||
assert!(not_found.is_err());
|
assert!(not_found.is_err());
|
||||||
|
|
||||||
// edit article
|
// edit article
|
||||||
|
@ -45,7 +45,7 @@ async fn test_create_read_and_edit_article() -> MyResult<()> {
|
||||||
previous_version: get_res.article.latest_version,
|
previous_version: get_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_form.new_text, edit_res.article.text);
|
assert_eq!(edit_form.new_text, edit_res.article.text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ async fn test_create_read_and_edit_article() -> MyResult<()> {
|
||||||
query: title.clone(),
|
query: title.clone(),
|
||||||
};
|
};
|
||||||
let search_res: Vec<DbArticle> =
|
let search_res: Vec<DbArticle> =
|
||||||
get_query(data.hostname_alpha, "search", Some(search_form)).await?;
|
get_query(&data.alpha.hostname, "search", Some(search_form)).await?;
|
||||||
assert_eq!(1, search_res.len());
|
assert_eq!(1, search_res.len());
|
||||||
assert_eq!(edit_res.article, search_res[0]);
|
assert_eq!(edit_res.article, search_res[0]);
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ async fn test_create_duplicate_article() -> MyResult<()> {
|
||||||
|
|
||||||
// create article
|
// create article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await;
|
||||||
assert!(create_res.is_err());
|
assert!(create_res.is_err());
|
||||||
|
|
||||||
data.stop()
|
data.stop()
|
||||||
|
@ -83,22 +83,23 @@ async fn test_follow_instance() -> MyResult<()> {
|
||||||
let data = TestData::start();
|
let data = TestData::start();
|
||||||
|
|
||||||
// check initial state
|
// check initial state
|
||||||
let alpha_instance: DbInstance = get(data.hostname_alpha, "instance").await?;
|
let alpha_instance: DbInstance = get(&data.alpha.hostname, "instance").await?;
|
||||||
assert_eq!(0, alpha_instance.follows.len());
|
assert_eq!(0, alpha_instance.follows.len());
|
||||||
let beta_instance: DbInstance = get(data.hostname_beta, "instance").await?;
|
let beta_instance: DbInstance = get(&data.beta.hostname, "instance").await?;
|
||||||
assert_eq!(0, beta_instance.followers.len());
|
assert_eq!(0, beta_instance.followers.len());
|
||||||
|
|
||||||
follow_instance(data.hostname_alpha, data.hostname_beta).await?;
|
follow_instance(&data.alpha.hostname, &data.beta.hostname).await?;
|
||||||
|
|
||||||
// check that follow was federated
|
// check that follow was federated
|
||||||
let beta_instance: DbInstance = get(data.hostname_beta, "instance").await?;
|
let beta_instance: DbInstance = get(&data.beta.hostname, "instance").await?;
|
||||||
assert_eq!(1, beta_instance.followers.len());
|
assert_eq!(1, beta_instance.followers.len());
|
||||||
|
|
||||||
let alpha_instance: DbInstance = get(data.hostname_alpha, "instance").await?;
|
let alpha_instance: DbInstance = get(&data.alpha.hostname, "instance").await?;
|
||||||
assert_eq!(1, alpha_instance.follows.len());
|
assert_eq!(1, alpha_instance.follows.len());
|
||||||
|
|
||||||
data.stop()
|
data.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
#[serial]
|
#[serial]
|
||||||
async fn test_synchronize_articles() -> MyResult<()> {
|
async fn test_synchronize_articles() -> MyResult<()> {
|
||||||
|
@ -106,7 +107,7 @@ async fn test_synchronize_articles() -> MyResult<()> {
|
||||||
|
|
||||||
// create article on alpha
|
// create article on alpha
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert_eq!(1, create_res.edits.len());
|
assert_eq!(1, create_res.edits.len());
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
@ -118,21 +119,25 @@ async fn test_synchronize_articles() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version,
|
previous_version: create_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
edit_article(data.hostname_alpha, &edit_form).await?;
|
edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
|
|
||||||
// article is not yet on beta
|
// article is not yet on beta
|
||||||
let get_res = get_article(data.hostname_beta, create_res.article.id).await;
|
let get_res = get_article(&data.beta.hostname, create_res.article.id).await;
|
||||||
assert!(get_res.is_err());
|
assert!(get_res.is_err());
|
||||||
|
|
||||||
// fetch alpha instance on beta, articles are also fetched automatically
|
// fetch alpha instance on beta, articles are also fetched automatically
|
||||||
let resolve_object = ResolveObject {
|
let resolve_object = ResolveObject {
|
||||||
id: Url::parse(&format!("http://{}", data.hostname_alpha))?,
|
id: Url::parse(&format!("http://{}", &data.alpha.hostname))?,
|
||||||
};
|
};
|
||||||
get_query::<DbInstance, _>(data.hostname_beta, "resolve_instance", Some(resolve_object))
|
get_query::<DbInstance, _>(
|
||||||
|
&data.beta.hostname,
|
||||||
|
"resolve_instance",
|
||||||
|
Some(resolve_object),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// get the article and compare
|
// get the article and compare
|
||||||
let get_res = get_article(data.hostname_beta, create_res.article.id).await?;
|
let get_res = get_article(&data.beta.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(create_res.article.ap_id, get_res.article.ap_id);
|
assert_eq!(create_res.article.ap_id, get_res.article.ap_id);
|
||||||
assert_eq!(title, get_res.article.title);
|
assert_eq!(title, get_res.article.title);
|
||||||
assert_eq!(2, get_res.edits.len());
|
assert_eq!(2, get_res.edits.len());
|
||||||
|
@ -147,16 +152,16 @@ async fn test_synchronize_articles() -> MyResult<()> {
|
||||||
async fn test_edit_local_article() -> MyResult<()> {
|
async fn test_edit_local_article() -> MyResult<()> {
|
||||||
let data = TestData::start();
|
let data = TestData::start();
|
||||||
|
|
||||||
follow_instance(data.hostname_alpha, data.hostname_beta).await?;
|
follow_instance(&data.alpha.hostname, &data.beta.hostname).await?;
|
||||||
|
|
||||||
// create new article
|
// create new article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_beta, title.clone()).await?;
|
let create_res = create_article(&data.beta.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
// article should be federated to alpha
|
// article should be federated to alpha
|
||||||
let get_res = get_article(data.hostname_alpha, create_res.article.id).await?;
|
let get_res = get_article(&data.alpha.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(create_res.article.title, get_res.article.title);
|
assert_eq!(create_res.article.title, get_res.article.title);
|
||||||
assert_eq!(1, get_res.edits.len());
|
assert_eq!(1, get_res.edits.len());
|
||||||
assert!(!get_res.article.local);
|
assert!(!get_res.article.local);
|
||||||
|
@ -169,7 +174,7 @@ async fn test_edit_local_article() -> MyResult<()> {
|
||||||
previous_version: get_res.article.latest_version,
|
previous_version: get_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_beta, &edit_form).await?;
|
let edit_res = edit_article(&data.beta.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_res.article.text, edit_form.new_text);
|
assert_eq!(edit_res.article.text, edit_form.new_text);
|
||||||
assert_eq!(edit_res.edits.len(), 2);
|
assert_eq!(edit_res.edits.len(), 2);
|
||||||
assert!(edit_res.edits[0]
|
assert!(edit_res.edits[0]
|
||||||
|
@ -178,7 +183,7 @@ async fn test_edit_local_article() -> MyResult<()> {
|
||||||
.starts_with(&edit_res.article.ap_id.to_string()));
|
.starts_with(&edit_res.article.ap_id.to_string()));
|
||||||
|
|
||||||
// edit should be federated to alpha
|
// edit should be federated to alpha
|
||||||
let get_res = get_article(data.hostname_alpha, edit_res.article.id).await?;
|
let get_res = get_article(&data.alpha.hostname, edit_res.article.id).await?;
|
||||||
assert_eq!(edit_res.article.title, get_res.article.title);
|
assert_eq!(edit_res.article.title, get_res.article.title);
|
||||||
assert_eq!(edit_res.edits.len(), 2);
|
assert_eq!(edit_res.edits.len(), 2);
|
||||||
assert_eq!(edit_res.article.text, get_res.article.text);
|
assert_eq!(edit_res.article.text, get_res.article.text);
|
||||||
|
@ -191,22 +196,22 @@ async fn test_edit_local_article() -> MyResult<()> {
|
||||||
async fn test_edit_remote_article() -> MyResult<()> {
|
async fn test_edit_remote_article() -> MyResult<()> {
|
||||||
let data = TestData::start();
|
let data = TestData::start();
|
||||||
|
|
||||||
follow_instance(data.hostname_alpha, data.hostname_beta).await?;
|
follow_instance(&data.alpha.hostname, &data.beta.hostname).await?;
|
||||||
follow_instance(data.hostname_gamma, data.hostname_beta).await?;
|
follow_instance(&data.gamma.hostname, &data.beta.hostname).await?;
|
||||||
|
|
||||||
// create new article
|
// create new article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_beta, title.clone()).await?;
|
let create_res = create_article(&data.beta.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
// article should be federated to alpha and gamma
|
// article should be federated to alpha and gamma
|
||||||
let get_res = get_article(data.hostname_alpha, create_res.article.id).await?;
|
let get_res = get_article(&data.alpha.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(create_res.article.title, get_res.article.title);
|
assert_eq!(create_res.article.title, get_res.article.title);
|
||||||
assert_eq!(1, get_res.edits.len());
|
assert_eq!(1, get_res.edits.len());
|
||||||
assert!(!get_res.article.local);
|
assert!(!get_res.article.local);
|
||||||
|
|
||||||
let get_res = get_article(data.hostname_gamma, create_res.article.id).await?;
|
let get_res = get_article(&data.gamma.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(create_res.article.title, get_res.article.title);
|
assert_eq!(create_res.article.title, get_res.article.title);
|
||||||
assert_eq!(create_res.article.text, get_res.article.text);
|
assert_eq!(create_res.article.text, get_res.article.text);
|
||||||
|
|
||||||
|
@ -216,7 +221,7 @@ async fn test_edit_remote_article() -> MyResult<()> {
|
||||||
previous_version: get_res.article.latest_version,
|
previous_version: get_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_form.new_text, edit_res.article.text);
|
assert_eq!(edit_form.new_text, edit_res.article.text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
assert!(!edit_res.article.local);
|
assert!(!edit_res.article.local);
|
||||||
|
@ -226,12 +231,12 @@ async fn test_edit_remote_article() -> MyResult<()> {
|
||||||
.starts_with(&edit_res.article.ap_id.to_string()));
|
.starts_with(&edit_res.article.ap_id.to_string()));
|
||||||
|
|
||||||
// edit should be federated to beta and gamma
|
// edit should be federated to beta and gamma
|
||||||
let get_res = get_article(data.hostname_alpha, create_res.article.id).await?;
|
let get_res = get_article(&data.alpha.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(edit_res.article.title, get_res.article.title);
|
assert_eq!(edit_res.article.title, get_res.article.title);
|
||||||
assert_eq!(edit_res.edits.len(), 2);
|
assert_eq!(edit_res.edits.len(), 2);
|
||||||
assert_eq!(edit_res.article.text, get_res.article.text);
|
assert_eq!(edit_res.article.text, get_res.article.text);
|
||||||
|
|
||||||
let get_res = get_article(data.hostname_gamma, create_res.article.id).await?;
|
let get_res = get_article(&data.gamma.hostname, create_res.article.id).await?;
|
||||||
assert_eq!(edit_res.article.title, get_res.article.title);
|
assert_eq!(edit_res.article.title, get_res.article.title);
|
||||||
assert_eq!(edit_res.edits.len(), 2);
|
assert_eq!(edit_res.edits.len(), 2);
|
||||||
assert_eq!(edit_res.article.text, get_res.article.text);
|
assert_eq!(edit_res.article.text, get_res.article.text);
|
||||||
|
@ -246,7 +251,7 @@ async fn test_local_edit_conflict() -> MyResult<()> {
|
||||||
|
|
||||||
// create new article
|
// create new article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
|
@ -257,7 +262,7 @@ async fn test_local_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version.clone(),
|
previous_version: create_res.article.latest_version.clone(),
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_res.article.text, edit_form.new_text);
|
assert_eq!(edit_res.article.text, edit_form.new_text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
|
|
||||||
|
@ -268,13 +273,13 @@ async fn test_local_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version,
|
previous_version: create_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article_with_conflict(data.hostname_alpha, &edit_form)
|
let edit_res = edit_article_with_conflict(&data.alpha.hostname, &edit_form)
|
||||||
.await?
|
.await?
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!("<<<<<<< ours\nIpsum Lorem\n||||||| original\nsome\nexample\ntext\n=======\nLorem Ipsum\n>>>>>>> theirs\n", edit_res.three_way_merge);
|
assert_eq!("<<<<<<< ours\nIpsum Lorem\n||||||| original\nsome\nexample\ntext\n=======\nLorem Ipsum\n>>>>>>> theirs\n", edit_res.three_way_merge);
|
||||||
|
|
||||||
let conflicts: Vec<ApiConflict> =
|
let conflicts: Vec<ApiConflict> =
|
||||||
get_query(data.hostname_alpha, "edit_conflicts", None::<()>).await?;
|
get_query(&data.alpha.hostname, "edit_conflicts", None::<()>).await?;
|
||||||
assert_eq!(1, conflicts.len());
|
assert_eq!(1, conflicts.len());
|
||||||
assert_eq!(conflicts[0], edit_res);
|
assert_eq!(conflicts[0], edit_res);
|
||||||
|
|
||||||
|
@ -284,11 +289,11 @@ async fn test_local_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: edit_res.previous_version,
|
previous_version: edit_res.previous_version,
|
||||||
resolve_conflict_id: Some(edit_res.id),
|
resolve_conflict_id: Some(edit_res.id),
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_form.new_text, edit_res.article.text);
|
assert_eq!(edit_form.new_text, edit_res.article.text);
|
||||||
|
|
||||||
let conflicts: Vec<ApiConflict> =
|
let conflicts: Vec<ApiConflict> =
|
||||||
get_query(data.hostname_alpha, "edit_conflicts", None::<()>).await?;
|
get_query(&data.alpha.hostname, "edit_conflicts", None::<()>).await?;
|
||||||
assert_eq!(0, conflicts.len());
|
assert_eq!(0, conflicts.len());
|
||||||
|
|
||||||
data.stop()
|
data.stop()
|
||||||
|
@ -299,11 +304,11 @@ async fn test_local_edit_conflict() -> MyResult<()> {
|
||||||
async fn test_federated_edit_conflict() -> MyResult<()> {
|
async fn test_federated_edit_conflict() -> MyResult<()> {
|
||||||
let data = TestData::start();
|
let data = TestData::start();
|
||||||
|
|
||||||
follow_instance(data.hostname_alpha, data.hostname_beta).await?;
|
follow_instance(&data.alpha.hostname, &data.beta.hostname).await?;
|
||||||
|
|
||||||
// create new article
|
// create new article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_beta, title.clone()).await?;
|
let create_res = create_article(&data.beta.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
|
@ -311,8 +316,12 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
|
||||||
let resolve_object = ResolveObject {
|
let resolve_object = ResolveObject {
|
||||||
id: create_res.article.ap_id.inner().clone(),
|
id: create_res.article.ap_id.inner().clone(),
|
||||||
};
|
};
|
||||||
let resolve_res: DbArticle =
|
let resolve_res: DbArticle = get_query(
|
||||||
get_query(data.hostname_gamma, "resolve_article", Some(resolve_object)).await?;
|
&data.gamma.hostname,
|
||||||
|
"resolve_article",
|
||||||
|
Some(resolve_object),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
assert_eq!(create_res.article.text, resolve_res.text);
|
assert_eq!(create_res.article.text, resolve_res.text);
|
||||||
|
|
||||||
// alpha edits article
|
// alpha edits article
|
||||||
|
@ -322,7 +331,7 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version.clone(),
|
previous_version: create_res.article.latest_version.clone(),
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_res.article.text, edit_form.new_text);
|
assert_eq!(edit_res.article.text, edit_form.new_text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
assert!(!edit_res.article.local);
|
assert!(!edit_res.article.local);
|
||||||
|
@ -339,13 +348,13 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version,
|
previous_version: create_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_gamma, &edit_form).await?;
|
let edit_res = edit_article(&data.gamma.hostname, &edit_form).await?;
|
||||||
assert_ne!(edit_form.new_text, edit_res.article.text);
|
assert_ne!(edit_form.new_text, edit_res.article.text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
assert!(!edit_res.article.local);
|
assert!(!edit_res.article.local);
|
||||||
|
|
||||||
let conflicts: Vec<ApiConflict> =
|
let conflicts: Vec<ApiConflict> =
|
||||||
get_query(data.hostname_gamma, "edit_conflicts", None::<()>).await?;
|
get_query(&data.gamma.hostname, "edit_conflicts", None::<()>).await?;
|
||||||
assert_eq!(1, conflicts.len());
|
assert_eq!(1, conflicts.len());
|
||||||
|
|
||||||
// resolve the conflict
|
// resolve the conflict
|
||||||
|
@ -355,12 +364,12 @@ async fn test_federated_edit_conflict() -> MyResult<()> {
|
||||||
previous_version: conflicts[0].previous_version.clone(),
|
previous_version: conflicts[0].previous_version.clone(),
|
||||||
resolve_conflict_id: Some(conflicts[0].id),
|
resolve_conflict_id: Some(conflicts[0].id),
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_gamma, &edit_form).await?;
|
let edit_res = edit_article(&data.gamma.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_form.new_text, edit_res.article.text);
|
assert_eq!(edit_form.new_text, edit_res.article.text);
|
||||||
assert_eq!(3, edit_res.edits.len());
|
assert_eq!(3, edit_res.edits.len());
|
||||||
|
|
||||||
let conflicts: Vec<ApubEdit> =
|
let conflicts: Vec<ApubEdit> =
|
||||||
get_query(data.hostname_gamma, "edit_conflicts", None::<()>).await?;
|
get_query(&data.gamma.hostname, "edit_conflicts", None::<()>).await?;
|
||||||
assert_eq!(0, conflicts.len());
|
assert_eq!(0, conflicts.len());
|
||||||
|
|
||||||
data.stop()
|
data.stop()
|
||||||
|
@ -373,7 +382,7 @@ async fn test_overlapping_edits_no_conflict() -> MyResult<()> {
|
||||||
|
|
||||||
// create new article
|
// create new article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
|
@ -384,7 +393,7 @@ async fn test_overlapping_edits_no_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version.clone(),
|
previous_version: create_res.article.latest_version.clone(),
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
assert_eq!(edit_res.article.text, edit_form.new_text);
|
assert_eq!(edit_res.article.text, edit_form.new_text);
|
||||||
assert_eq!(2, edit_res.edits.len());
|
assert_eq!(2, edit_res.edits.len());
|
||||||
|
|
||||||
|
@ -395,9 +404,9 @@ async fn test_overlapping_edits_no_conflict() -> MyResult<()> {
|
||||||
previous_version: create_res.article.latest_version,
|
previous_version: create_res.article.latest_version,
|
||||||
resolve_conflict_id: None,
|
resolve_conflict_id: None,
|
||||||
};
|
};
|
||||||
let edit_res = edit_article(data.hostname_alpha, &edit_form).await?;
|
let edit_res = edit_article(&data.alpha.hostname, &edit_form).await?;
|
||||||
let conflicts: Vec<ApiConflict> =
|
let conflicts: Vec<ApiConflict> =
|
||||||
get_query(data.hostname_alpha, "edit_conflicts", None::<()>).await?;
|
get_query(&data.alpha.hostname, "edit_conflicts", None::<()>).await?;
|
||||||
assert_eq!(0, conflicts.len());
|
assert_eq!(0, conflicts.len());
|
||||||
assert_eq!(3, edit_res.edits.len());
|
assert_eq!(3, edit_res.edits.len());
|
||||||
assert_eq!("my\nexample\narticle\n", edit_res.article.text);
|
assert_eq!("my\nexample\narticle\n", edit_res.article.text);
|
||||||
|
@ -412,7 +421,7 @@ async fn test_fork_article() -> MyResult<()> {
|
||||||
|
|
||||||
// create article
|
// create article
|
||||||
let title = "Manu_Chao".to_string();
|
let title = "Manu_Chao".to_string();
|
||||||
let create_res = create_article(data.hostname_alpha, title.clone()).await?;
|
let create_res = create_article(&data.alpha.hostname, title.clone()).await?;
|
||||||
assert_eq!(title, create_res.article.title);
|
assert_eq!(title, create_res.article.title);
|
||||||
assert!(create_res.article.local);
|
assert!(create_res.article.local);
|
||||||
|
|
||||||
|
@ -421,7 +430,7 @@ async fn test_fork_article() -> MyResult<()> {
|
||||||
id: create_res.article.ap_id.into_inner(),
|
id: create_res.article.ap_id.into_inner(),
|
||||||
};
|
};
|
||||||
let resolve_res: ArticleView =
|
let resolve_res: ArticleView =
|
||||||
get_query(data.hostname_beta, "resolve_article", Some(resolve_object)).await?;
|
get_query(&data.beta.hostname, "resolve_article", Some(resolve_object)).await?;
|
||||||
let resolved_article = resolve_res.article;
|
let resolved_article = resolve_res.article;
|
||||||
assert_eq!(create_res.edits.len(), resolve_res.edits.len());
|
assert_eq!(create_res.edits.len(), resolve_res.edits.len());
|
||||||
|
|
||||||
|
@ -429,7 +438,7 @@ async fn test_fork_article() -> MyResult<()> {
|
||||||
let fork_form = ForkArticleData {
|
let fork_form = ForkArticleData {
|
||||||
article_id: resolved_article.id,
|
article_id: resolved_article.id,
|
||||||
};
|
};
|
||||||
let fork_res: ArticleView = post(data.hostname_beta, "article/fork", &fork_form).await?;
|
let fork_res: ArticleView = post(&data.beta.hostname, "article/fork", &fork_form).await?;
|
||||||
let forked_article = fork_res.article;
|
let forked_article = fork_res.article;
|
||||||
assert_eq!(resolved_article.title, forked_article.title);
|
assert_eq!(resolved_article.title, forked_article.title);
|
||||||
assert_eq!(resolved_article.text, forked_article.text);
|
assert_eq!(resolved_article.text, forked_article.text);
|
||||||
|
@ -441,7 +450,7 @@ async fn test_fork_article() -> MyResult<()> {
|
||||||
assert_ne!(resolved_article.ap_id, forked_article.ap_id);
|
assert_ne!(resolved_article.ap_id, forked_article.ap_id);
|
||||||
assert!(forked_article.local);
|
assert!(forked_article.local);
|
||||||
|
|
||||||
let beta_instance: DbInstance = get(data.hostname_beta, "instance").await?;
|
let beta_instance: DbInstance = get(&data.beta.hostname, "instance").await?;
|
||||||
assert_eq!(forked_article.instance_id, beta_instance.ap_id);
|
assert_eq!(forked_article.instance_id, beta_instance.ap_id);
|
||||||
|
|
||||||
// now search returns two articles for this title (original and forked)
|
// now search returns two articles for this title (original and forked)
|
||||||
|
@ -449,7 +458,7 @@ async fn test_fork_article() -> MyResult<()> {
|
||||||
query: title.clone(),
|
query: title.clone(),
|
||||||
};
|
};
|
||||||
let search_res: Vec<DbArticle> =
|
let search_res: Vec<DbArticle> =
|
||||||
get_query(data.hostname_beta, "search", Some(search_form)).await?;
|
get_query(&data.beta.hostname, "search", Some(search_form)).await?;
|
||||||
assert_eq!(2, search_res.len());
|
assert_eq!(2, search_res.len());
|
||||||
|
|
||||||
data.stop()
|
data.stop()
|
||||||
|
|
Loading…
Reference in a new issue