WIP
test / test (push) Failing after 18s
Details
test / test (push) Failing after 18s
Details
This commit is contained in:
parent
62cd2f8f42
commit
e6fa834473
11
README.md
11
README.md
|
@ -10,8 +10,9 @@ gleam shell # Run an Erlang shell
|
|||
|
||||
## TODO
|
||||
|
||||
- [X] Handle link GET
|
||||
- [X] Handle link POST
|
||||
- [] Handle file POST
|
||||
- [] Handle file GET
|
||||
- [] Web Frontend
|
||||
- [x] Handle link GET
|
||||
- [x] Handle link POST
|
||||
- [ ] Handle file POST
|
||||
- [ ] Handle file GET
|
||||
- [ ] Web Frontend
|
||||
- [ ] fix config loading from env
|
||||
|
|
|
@ -69,25 +69,15 @@ pub fn load_config_from_env() -> Config {
|
|||
postgres_pool_size: 15,
|
||||
)
|
||||
Config(
|
||||
port: "PORT"
|
||||
|> get_int_or(defaults.port),
|
||||
max_bytes: "MAX_BYTES"
|
||||
|> get_int_or(defaults.max_bytes),
|
||||
url_root: "URL_ROOT"
|
||||
|> get_string_or(defaults.url_root),
|
||||
secret_key_base: "SECRET_KEY_BASE"
|
||||
|> get_string_or(defaults.secret_key_base),
|
||||
postgres_host: "POSTGRES_HOST"
|
||||
|> get_string_or(defaults.postgres_host),
|
||||
postgres_db: "POSTGRES_DB"
|
||||
|> get_string_or(defaults.postgres_db),
|
||||
postgres_user: "POSTGRES_USER"
|
||||
|> get_string_or(defaults.postgres_user),
|
||||
postgres_password: "POSTGRES_PASSWORD"
|
||||
|> get_string_or(defaults.postgres_password),
|
||||
postgres_pool_size: "POSTGRES_POOL_SIZE"
|
||||
|> get_int_or(defaults.postgres_pool_size),
|
||||
postgres_port: "POSTGRES_PORT"
|
||||
|> get_int_or(defaults.postgres_port),
|
||||
port: get_int_or("PORT", defaults.port),
|
||||
max_bytes: get_int_or("MAX_BYTES", defaults.max_bytes),
|
||||
url_root: get_string_or("URL_ROOT", defaults.url_root),
|
||||
secret_key_base: get_string_or("SECRET_KEY_BASE", defaults.secret_key_base),
|
||||
postgres_host: get_string_or("PG_HOST", defaults.postgres_host),
|
||||
postgres_db: get_string_or("PG_DB", defaults.postgres_db),
|
||||
postgres_user: get_string_or("PG_USER", defaults.postgres_user),
|
||||
postgres_password: get_string_or("PG_PASSWORD", defaults.postgres_password),
|
||||
postgres_pool_size: get_int_or("PG_POOL_SIZE", defaults.postgres_pool_size),
|
||||
postgres_port: get_int_or("PG_PORT", defaults.postgres_port),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -11,10 +11,10 @@ import ids/cuid
|
|||
import wisp.{type Request, type Response}
|
||||
|
||||
const schema = "
|
||||
CREATE TABLE IF NOT EXISTS \"File\" (
|
||||
Cuid CHAR(25) PRIMARY KEY,
|
||||
Md5Hash CHAR(32)
|
||||
FileName TEXT
|
||||
CREATE TABLE IF NOT EXISTS \"file\" (
|
||||
cuid CHAR(25) PRIMARY KEY,
|
||||
md5hash CHAR(32),
|
||||
fileName TEXT
|
||||
);
|
||||
"
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub fn prepare_database(ctx: Context) -> Result(Nil, pgo.QueryError) {
|
|||
|
||||
pub fn store(file: File, ctx: Context) -> Result(String, Nil) {
|
||||
let sql =
|
||||
"INSERT INTO \"File\" (Cuid, Md5Hash) VALUES ($1, $2) RETURNING Cuid;"
|
||||
"INSERT INTO \"file\" (cuid, md5hash) VALUES ($1, $2) RETURNING cuid;"
|
||||
case
|
||||
pgo.execute(
|
||||
sql,
|
||||
|
@ -45,7 +45,7 @@ pub fn store(file: File, ctx: Context) -> Result(String, Nil) {
|
|||
}
|
||||
|
||||
pub fn retrieve(cuid: String, ctx: Context) -> Result(File, Nil) {
|
||||
let sql = "SELECT Cuid,Md5Hash,FileName FROM \"File\" WHERE Cuid = $1;"
|
||||
let sql = "SELECT cuid,md5hash,filename FROM \"file\" WHERE cuid = $1;"
|
||||
case
|
||||
pgo.execute(
|
||||
sql,
|
||||
|
|
|
@ -10,9 +10,9 @@ import ids/cuid
|
|||
import wisp.{type Request, type Response}
|
||||
|
||||
const schema = "
|
||||
CREATE TABLE IF NOT EXISTS \"Link\" (
|
||||
Cuid CHAR(25) PRIMARY KEY,
|
||||
TargetURL TEXT
|
||||
CREATE TABLE IF NOT EXISTS \"link\" (
|
||||
cuid CHAR(25) PRIMARY KEY,
|
||||
targeturl TEXT
|
||||
);
|
||||
"
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub fn prepare_database(ctx: Context) -> Result(Nil, pgo.QueryError) {
|
|||
|
||||
pub fn store(link: Link, ctx: Context) -> Result(String, Nil) {
|
||||
let sql =
|
||||
"INSERT INTO \"Link\" (Cuid, TargetURL) VALUES ($1, $2) RETURNING Cuid;"
|
||||
"INSERT INTO \"link\" (cuid, targeturl) VALUES ($1, $2) RETURNING cuid;"
|
||||
case
|
||||
pgo.execute(
|
||||
sql,
|
||||
|
@ -43,7 +43,7 @@ pub fn store(link: Link, ctx: Context) -> Result(String, Nil) {
|
|||
}
|
||||
|
||||
pub fn retrieve(cuid: String, ctx: Context) -> Result(Link, Nil) {
|
||||
let sql = "SELECT Cuid,TargetURL FROM \"Link\" WHERE Cuid = $1;"
|
||||
let sql = "SELECT cuid,targeturl FROM \"link\" WHERE cuid = $1;"
|
||||
case
|
||||
pgo.execute(
|
||||
sql,
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import app/config.{type Context, Config, Context}
|
||||
import app/web/file
|
||||
import gleam/dynamic
|
||||
import gleam/option.{None, Some}
|
||||
import gleam/pgo
|
||||
import gleam/option.{Some}
|
||||
import gleam/pgo.{type Returned}
|
||||
import gleam/string
|
||||
import gleeunit/should
|
||||
import ids/cuid
|
||||
|
||||
const test_config = Config(
|
||||
port: 8080,
|
||||
|
@ -20,6 +21,7 @@ const test_config = Config(
|
|||
)
|
||||
|
||||
fn with_context(testcase: fn(Context) -> t) -> t {
|
||||
let assert Ok(cuid) = cuid.start()
|
||||
let ctx =
|
||||
Context(
|
||||
db: pgo.Config(
|
||||
|
@ -33,6 +35,7 @@ fn with_context(testcase: fn(Context) -> t) -> t {
|
|||
)
|
||||
|> pgo.connect,
|
||||
config: test_config,
|
||||
cuid: cuid,
|
||||
)
|
||||
|
||||
case file.prepare_database(ctx) {
|
||||
|
@ -44,25 +47,41 @@ fn with_context(testcase: fn(Context) -> t) -> t {
|
|||
ret
|
||||
}
|
||||
Error(e) -> {
|
||||
e |> string.inspect |> panic
|
||||
panic as string.inspect(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn null_test() {
|
||||
fn cleanup() {
|
||||
use ctx <- with_context()
|
||||
let assert Ok(_) =
|
||||
pgo.execute("DROP TABLE file;", ctx.db, [], dynamic.dynamic)
|
||||
}
|
||||
|
||||
pub fn prepare_database_test() {
|
||||
use ctx <- with_context()
|
||||
let res =
|
||||
pgo.execute(
|
||||
"select $1",
|
||||
"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'file';",
|
||||
ctx.db,
|
||||
[pgo.null()],
|
||||
dynamic.element(0, dynamic.optional(dynamic.int)),
|
||||
[],
|
||||
dynamic.tuple2(dynamic.string, dynamic.string),
|
||||
)
|
||||
|> should.equal(Ok(pgo.Returned(count: 1, rows: [None])))
|
||||
|
||||
res
|
||||
|> should.be_ok
|
||||
|> fn(x: Returned(#(String, String))) { x.rows }
|
||||
|> should.equal([
|
||||
#("cuid", "character"),
|
||||
#("md5hash", "character"),
|
||||
#("filename", "text"),
|
||||
])
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
pub fn hash_to_path_test() {
|
||||
"f7b478961451483b8c251c788750d5ef"
|
||||
|> file.hash_to_path
|
||||
|> should.equal(["f7", "b4", "78961451483b8c251c788750d5ef"])
|
||||
|> should.equal("/f7/b4/78961451483b8c251c788750d5ef")
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import app/config.{type Context, Config, Context}
|
||||
import app/web/link.{Link}
|
||||
import gleam/dynamic
|
||||
import gleam/option.{None, Some}
|
||||
import gleam/pgo
|
||||
import gleam/result
|
||||
import gleam/option.{Some}
|
||||
import gleam/pgo.{type Returned}
|
||||
import gleam/string
|
||||
import gleam/uri
|
||||
import gleeunit/should
|
||||
import ids/nanoid
|
||||
import ids/cuid
|
||||
|
||||
const test_config = Config(
|
||||
port: 8080,
|
||||
|
@ -23,6 +22,7 @@ const test_config = Config(
|
|||
)
|
||||
|
||||
fn with_context(testcase: fn(Context) -> t) -> t {
|
||||
let assert Ok(cuid) = cuid.start()
|
||||
let ctx =
|
||||
Context(
|
||||
db: pgo.Config(
|
||||
|
@ -36,6 +36,7 @@ fn with_context(testcase: fn(Context) -> t) -> t {
|
|||
)
|
||||
|> pgo.connect,
|
||||
config: test_config,
|
||||
cuid: cuid,
|
||||
)
|
||||
|
||||
case link.prepare_database(ctx) {
|
||||
|
@ -52,39 +53,42 @@ fn with_context(testcase: fn(Context) -> t) -> t {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn null_test() {
|
||||
fn cleanup() {
|
||||
use ctx <- with_context()
|
||||
let assert Ok(_) =
|
||||
pgo.execute("DROP TABLE link;", ctx.db, [], dynamic.dynamic)
|
||||
}
|
||||
|
||||
pub fn prepare_database_test() {
|
||||
use ctx <- with_context()
|
||||
let res =
|
||||
pgo.execute(
|
||||
"select $1",
|
||||
"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'link';",
|
||||
ctx.db,
|
||||
[pgo.null()],
|
||||
dynamic.element(0, dynamic.optional(dynamic.int)),
|
||||
[],
|
||||
dynamic.tuple2(dynamic.string, dynamic.string),
|
||||
)
|
||||
|> should.equal(Ok(pgo.Returned(count: 1, rows: [None])))
|
||||
|
||||
res
|
||||
|> should.be_ok
|
||||
|> fn(x: Returned(#(String, String))) { x.rows }
|
||||
|> should.equal([#("cuid", "character"), #("targeturl", "text")])
|
||||
|
||||
cleanup()
|
||||
}
|
||||
|
||||
pub fn generate_url_test() {
|
||||
use ctx <- with_context()
|
||||
let test_id = Ok("testid_generate_url")
|
||||
|
||||
link.generate_url(test_id, ctx)
|
||||
|> should.equal(uri.parse("http://localhost:8080/l/testid_generate_url"))
|
||||
}
|
||||
|
||||
pub fn store_link_test() {
|
||||
pub fn store_retreive_test() {
|
||||
use ctx <- with_context()
|
||||
let assert Ok(test_url) = uri.parse("http://example.com/")
|
||||
let test_id = nanoid.generate()
|
||||
let test_id = cuid.generate(ctx.cuid)
|
||||
|
||||
let stored_nano_id =
|
||||
let cuid =
|
||||
Link(test_id, test_url)
|
||||
|> link.store(ctx)
|
||||
|> result.try_recover(fn(e) { e |> string.inspect |> Ok })
|
||||
|> result.unwrap("Undefined Error")
|
||||
|> should.be_ok
|
||||
|
||||
stored_nano_id |> should.equal(test_id)
|
||||
cuid |> should.equal(test_id)
|
||||
|
||||
let assert Ok(stored_link) = stored_nano_id |> link.retrieve(ctx)
|
||||
let assert Ok(stored_link) = cuid |> link.retrieve(ctx)
|
||||
stored_link.target_url |> should.equal(test_url)
|
||||
}
|
||||
|
|
|
@ -2,8 +2,26 @@ services:
|
|||
db:
|
||||
image: postgres:latest
|
||||
environment:
|
||||
- POSTGRES_USER=dumptruck
|
||||
- POSTGRES_PASSWORD=dumptruck
|
||||
- POSTGRES_DB=dumptruck
|
||||
POSTGRES_USER: dumptruck
|
||||
POSTGRES_PASSWORD: dumptruck
|
||||
POSTGRES_DB: dumptruck
|
||||
ports:
|
||||
- "5432:5432"
|
||||
|
||||
frontend:
|
||||
image: dpage/pgadmin4
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: "test@example.com"
|
||||
PGADMIN_DEFAULT_PASSWORD: "test"
|
||||
PGADMIN_LISTEN_PORT: "80"
|
||||
PGADMIN_CONFIG_SERVER_MODE: "False"
|
||||
PGADMIN_CONFIG_MASTER_PASSWORD_REQUIRED: "False"
|
||||
depends_on:
|
||||
- "db"
|
||||
volumes:
|
||||
- read_only: true
|
||||
source: "servers.json"
|
||||
target: "/pgadmin4/servers.json"
|
||||
type: bind
|
||||
ports:
|
||||
- "8080:80"
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Servers": {
|
||||
"1": {
|
||||
"Group": "Servers",
|
||||
"Name": "Docker",
|
||||
"Host": "db",
|
||||
"Port": 5432,
|
||||
"MaintenanceDB": "dumptruck",
|
||||
"Username": "dumptruck",
|
||||
"Password": "dumptruck",
|
||||
"SSLMode": "prefer",
|
||||
"Favorite": true
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue