Skip to content

Commit 9142ce1

Browse files
authored
feat(eventually-test): add acceptance tests to raise coverage (#83)
1 parent 89615b6 commit 9142ce1

6 files changed

Lines changed: 96 additions & 13 deletions

File tree

eventually-test/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ tokio = { version = "0.2", features = ["sync"] }
2323
tokio-postgres = "0.5"
2424
femme = "2.1.0"
2525
anyhow = "1.0"
26+
27+
[dev-dependencies]
28+
reqwest = { version = "0.10", features = ["json"] }
29+
lazy_static = "1.4"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use envconfig::Envconfig;
2+
3+
use eventually_test::config::Config;
4+
5+
fn main() -> anyhow::Result<()> {
6+
let config = Config::init()?;
7+
smol::run(eventually_test::run(config))
8+
}

eventually-test/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use envconfig::Envconfig;
22
use envconfig_derive::Envconfig;
33

44
#[derive(Envconfig)]
5-
pub(crate) struct Config {
5+
pub struct Config {
66
#[envconfig(from = "DB_HOST", default = "localhost")]
77
pub db_host: String,
88

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
mod api;
2-
mod config;
3-
mod order;
2+
pub mod config;
3+
pub mod order;
44
mod state;
55

66
use std::sync::Arc;
77

8-
use envconfig::Envconfig;
9-
108
use eventually::aggregate::Optional;
119
use eventually::inmemory::EventStoreBuilder;
1210
use eventually::{AggregateRootBuilder, Repository};
@@ -16,13 +14,7 @@ use tokio::sync::RwLock;
1614
use crate::config::Config;
1715
use crate::order::OrderAggregate;
1816

19-
fn main() -> anyhow::Result<()> {
20-
smol::run(run())
21-
}
22-
23-
async fn run() -> anyhow::Result<()> {
24-
let config = Config::init()?;
25-
17+
pub async fn run(config: Config) -> anyhow::Result<()> {
2618
femme::with_level(config.log_level);
2719

2820
// Aggregate target: in this case it's empty, but usually it would use

eventually-test/src/order.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl OrderItems {
4242
}
4343
}
4444

45-
#[derive(Debug, Clone, Serialize, Deserialize)]
45+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
4646
#[serde(tag = "state")]
4747
pub enum OrderState {
4848
Editable { updated_at: DateTime<Utc> },
@@ -52,12 +52,35 @@ pub enum OrderState {
5252

5353
#[derive(Debug, Clone, Serialize, Deserialize)]
5454
pub struct Order {
55+
#[serde(skip_serializing)]
5556
id: String,
5657
created_at: DateTime<Utc>,
5758
items: Vec<OrderItem>,
5859
state: OrderState,
5960
}
6061

62+
impl Order {
63+
pub fn created_at(&self) -> DateTime<Utc> {
64+
self.created_at
65+
}
66+
67+
pub fn items(&self) -> &Vec<OrderItem> {
68+
&self.items
69+
}
70+
71+
pub fn state(&self) -> OrderState {
72+
self.state
73+
}
74+
75+
pub fn is_editable(&self) -> bool {
76+
if let OrderState::Editable { .. } = self.state {
77+
return true;
78+
}
79+
80+
false
81+
}
82+
}
83+
6184
#[derive(Debug)]
6285
pub enum OrderCommand {
6386
Create,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
use std::sync::atomic::AtomicBool;
2+
use std::sync::Once;
3+
use std::thread;
4+
5+
use chrono::Utc;
6+
7+
use envconfig::Envconfig;
8+
9+
use lazy_static::lazy_static;
10+
11+
use eventually_test::config::Config;
12+
use eventually_test::order::Order;
13+
14+
static START: Once = Once::new();
15+
16+
lazy_static! {
17+
static ref SERVER_STARTED: AtomicBool = AtomicBool::default();
18+
}
19+
20+
fn setup() {
21+
START.call_once(|| {
22+
thread::spawn(move || {
23+
let config = Config::init().unwrap();
24+
SERVER_STARTED.store(true, std::sync::atomic::Ordering::SeqCst);
25+
26+
smol::run(eventually_test::run(config));
27+
});
28+
});
29+
30+
while !SERVER_STARTED.load(std::sync::atomic::Ordering::SeqCst) {}
31+
}
32+
33+
#[test]
34+
fn it_creates_an_order_successfully() {
35+
setup();
36+
37+
smol::run(async {
38+
let url = format!("http://localhost:8080/orders/test/create");
39+
let client = reqwest::Client::new();
40+
41+
let start = Utc::now();
42+
43+
let root: Order = client
44+
.post(&url)
45+
.send()
46+
.await
47+
.unwrap()
48+
.json()
49+
.await
50+
.unwrap();
51+
52+
assert!(root.created_at() >= start);
53+
assert!(root.is_editable());
54+
assert!(root.items().is_empty());
55+
});
56+
}

0 commit comments

Comments
 (0)