Skip to content

Commit

Permalink
Merge pull request #14 from supabase/test/integration
Browse files Browse the repository at this point in the history
Add integration tests
  • Loading branch information
soedirgo authored May 24, 2020
2 parents 11d6ae7 + cd36422 commit 81107d4
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 12 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ edition = "2018"
[dependencies]
reqwest = { version = "0.10", features = ["json"] }
tokio = { version = "0.2", features = ["full"] }

[dev-dependencies]
json = "0.12"
41 changes: 30 additions & 11 deletions src/builder.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
extern crate reqwest;

use reqwest::{
header::{HeaderMap, HeaderValue},
Client, Error, Method, Response,
Expand All @@ -19,8 +17,9 @@ pub struct Builder {
// TODO: Complex filters (not, and, or)
// TODO: Exact, planned, estimated count (HEAD verb)
// TODO: Response format
// TODO: Embedded resources
// TODO: Content type (csv, etc.)
// TODO: Resource embedding (embedded filters, etc.)
// TODO: Content-Type (text/csv, etc.)
// TODO: Reject update/delete w/o filters
impl Builder {
pub fn new<S>(url: S, schema: Option<String>) -> Self
where
Expand Down Expand Up @@ -126,10 +125,9 @@ impl Builder {
S: Into<String>,
{
self.method = Method::POST;
self.headers.append(
self.headers.insert(
"Prefer",
// Maybe check if this works as intended...
HeaderValue::from_static("return=representation; resolution=merge-duplicates"),
HeaderValue::from_static("return=representation,resolution=merge-duplicates"),
);
self.body = Some(body.into());
self
Expand All @@ -143,7 +141,7 @@ impl Builder {
{
self.method = Method::PUT;
self.headers
.append("Prefer", HeaderValue::from_static("return=representation"));
.insert("Prefer", HeaderValue::from_static("return=representation"));
self.queries
.push((primary_column.into(), format!("eq.{}", key.into())));
self.body = Some(body.into());
Expand All @@ -156,15 +154,15 @@ impl Builder {
{
self.method = Method::PATCH;
self.headers
.append("Prefer", HeaderValue::from_static("return=representation"));
.insert("Prefer", HeaderValue::from_static("return=representation"));
self.body = Some(body.into());
self
}

pub fn delete(mut self) -> Self {
self.method = Method::DELETE;
self.headers
.append("Prefer", HeaderValue::from_static("return=representation"));
.insert("Prefer", HeaderValue::from_static("return=representation"));
self
}

Expand All @@ -189,6 +187,10 @@ impl Builder {
self.headers
.append(key, HeaderValue::from_str(&schema).unwrap());
}
if self.method != Method::GET && self.method != Method::HEAD {
self.headers
.insert("Content-Type", HeaderValue::from_static("application/json"));
}
req = req.headers(self.headers).query(&self.queries);
if let Some(body) = self.body {
req = req.body(body);
Expand Down Expand Up @@ -278,7 +280,7 @@ mod tests {
let builder = Builder::new(TABLE_URL, None).upsert("ignored");
assert_eq!(
builder.headers.get("Prefer").unwrap(),
HeaderValue::from_static("return=representation; resolution=merge-duplicates")
HeaderValue::from_static("return=representation,resolution=merge-duplicates")
);
}

Expand All @@ -303,4 +305,21 @@ mod tests {
assert_eq!(builder.body.unwrap(), "{\"a\": 1, \"b\": 2}");
assert_eq!(builder.is_rpc, true);
}

#[test]
fn chain_filters() -> Result<(), Box<dyn std::error::Error>> {
let builder = Builder::new(TABLE_URL, None)
.eq("username", "supabot")
.neq("message", "hello world")
.gte("channel_id", "1")
.select("*");

let queries = builder.queries;
assert_eq!(queries.len(), 4);
assert!(queries.contains(&("username".into(), "eq.supabot".into())));
assert!(queries.contains(&("message".into(), "neq.hello world".into())));
assert!(queries.contains(&("channel_id".into(), "gte.1".into())));

Ok(())
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
extern crate reqwest;

mod builder;
mod filter;

Expand Down
159 changes: 159 additions & 0 deletions tests/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
use postgrest::Postgrest;

use std::error::Error;

const REST_URL: &str = "http://localhost:3000";

#[tokio::test]
async fn basic_data() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("users")
.select("username")
.eq("status", "OFFLINE")
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(body[0]["username"], "kiwicopple");

Ok(())
}

#[tokio::test]
async fn relational_join() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("channels")
.select("slug, messages(message)")
.eq("slug", "public")
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(body[0]["messages"][0]["message"], "Hello World 👋");
assert_eq!(body[0]["slug"], "public");

Ok(())
}

#[tokio::test]
async fn insert() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("messages")
.insert(r#"[{"message": "Test message 0", "channel_id": 1, "username": "kiwicopple"}]"#)
.execute()
.await?;
let status = resp.status();

assert_eq!(status.as_u16(), 201);

Ok(())
}

#[tokio::test]
async fn upsert() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("users")
.upsert(
r#"[{"username": "dragarcia", "status": "OFFLINE"},
{"username": "supabot2", "status": "ONLINE"}]"#,
)
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(body[0]["username"], "dragarcia");
assert_eq!(body[1]["username"], "supabot2");

Ok(())
}

#[tokio::test]
async fn upsert_existing() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("users")
.upsert(r#"{"username": "dragarcia", "status": "ONLINE"}"#)
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(body[0]["username"], "dragarcia");
assert_eq!(body[0]["status"], "ONLINE");

Ok(())
}

#[tokio::test]
async fn upsert_nonexisting() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("users")
.upsert(r#"{"username": "supabot3", "status": "ONLINE"}"#)
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(body[0]["username"], "supabot3");
assert_eq!(body[0]["status"], "ONLINE");

Ok(())
}

#[tokio::test]
async fn update() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("users")
.eq("status", "ONLINE")
.update(r#"{"status": "ONLINE"}"#)
.execute()
.await?;
let status = resp.status();
let body = resp.text().await?;
let body = json::parse(&body)?;

assert_eq!(status.as_u16(), 200);
assert_eq!(body[0]["status"], "ONLINE");

Ok(())
}

#[tokio::test]
async fn delete() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.from("messages")
.neq("username", "supabot")
.delete()
.execute()
.await?;
let status = resp.status();

assert_eq!(status.as_u16(), 200);

Ok(())
}

#[tokio::test]
async fn rpc() -> Result<(), Box<dyn Error>> {
let client = Postgrest::new(REST_URL);
let resp = client
.rpc("get_status", r#"{"name_param": "leroyjenkins"}"#)
.execute()
.await?;
let body = resp.text().await?;
let body = json::parse(&body)?;

assert!(body.is_null());

Ok(())
}
2 changes: 1 addition & 1 deletion tests/db/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3"
services:
rest:
image: postgrest/postgrest
image: postgrest/postgrest:v7.0.1
ports:
- "3000:3000"
environment:
Expand Down
Loading

0 comments on commit 81107d4

Please sign in to comment.