Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions backend/src/utils/routing.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use hyper::{Body, Request, Response, StatusCode, header};
use core::prelude::v1::derive;
use std::option::Option::None;
use std::result::Result::Ok;
use std::string::ToString;
use std::{collections::HashMap};
use std::convert::{From, Infallible};
use std::sync::Arc;
use chrono::{DateTime, Local};
use rand;
use rand::seq::IteratorRandom;
use serde::Serialize;

Expand All @@ -25,6 +26,11 @@ struct ProblemResponse {
difficulty: Option<f64>,
}

#[derive(Serialize)]
struct ErrorResponse {
message: String,
}

async fn get_parameter(req: &Request<Body>) -> HashMap<String, String> {
let query = req.uri().query().unwrap_or("");
url::form_urlencoded::parse(query.as_bytes())
Expand Down Expand Up @@ -99,8 +105,14 @@ pub async fn router(req: Request<Body>, state: Arc<AppState>) -> Result<Response
Ok(with_cors_headers(Response::new(Body::from(body))))
}
None => {
let mut not_found = Response::new(Body::from("No problem found in given range."));
let error_body = serde_json::to_string(&ErrorResponse {
message: "指定Diff範囲に該当する問題がありませんでした".to_string(),
}).unwrap();

let mut not_found = Response::new(Body::from(error_body));
*not_found.status_mut() = StatusCode::NOT_FOUND;
not_found.headers_mut().insert(header::CONTENT_TYPE, "application/json".parse().unwrap());

Ok(with_cors_headers(not_found))
}
}
Expand Down
23 changes: 14 additions & 9 deletions backend/tests/routing_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@ fn build_test_state() -> Arc<AppState> {
ProblemModel { difficulty: Some(1000.0) },
);

let problems = vec![
Problem {
id: "abc001_a".to_string(),
contest_id: "abc001".to_string(),
name: "A - Test Problem".to_string(),
}
];
let problems = vec![Problem {
id: "abc001_a".to_string(),
contest_id: "abc001".to_string(),
name: "A - Test Problem".to_string(),
}];

Arc::new(AppState {
problems,
Expand Down Expand Up @@ -56,7 +54,14 @@ async fn test_not_found_path() {
async fn test_not_found_problem() {
let (status, body) = build_and_send(Method::GET, "/?under=0&over=500").await;
assert_eq!(status, StatusCode::NOT_FOUND);
assert_eq!(body, "No problem found in given range.");

#[derive(serde::Deserialize)]
struct ErrorResponse {
message: String,
}

let err: ErrorResponse = serde_json::from_str(&body).unwrap();
assert_eq!(err.message, "指定Diff範囲に該当する問題がありませんでした");
}

#[tokio::test]
Expand All @@ -70,7 +75,7 @@ async fn test_under_greater_than_over() {
async fn test_random_range() {
let (status, body) = build_and_send(Method::GET, "/?under=500&over=1500").await;
assert_eq!(status, StatusCode::OK);

#[derive(serde::Deserialize)]
struct ProblemResponse {
id: String,
Expand Down
49 changes: 34 additions & 15 deletions frontend/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,28 @@
`${API_URL}/?under=${under_diff}&over=${over_diff}`
);

if (res.status === 404) {
const data = await res.json();
throw new Error(data.message ?? "指定範囲内に該当する問題がありませんでした");
}

if (!res.ok) {
throw new Error(`HTTPエラー: ${res.status}`);
}

const json: Problem = await res.json();
result = json;

setTimeout(() => {
result = json;
loading = false;
}, 1050);
} catch (err) {
errorMessage = (err as Error).message;
result = null;
setTimeout(() => {
errorMessage = (err as Error).message;
result = null;
loading = false;
}, 1050);
}

setTimeout(() => {
loading = false;
}, 2200);
}
</script>

Expand All @@ -63,20 +71,17 @@
<p class="text-destructive mb-2 text-sm">最低Diffが負の値になっています</p>
{/if}

{#if errorMessage}
<p class="text-destructive mb-2 text-sm">{errorMessage}</p>
{/if}

<div class="flex items-center gap-2">
<Input type="number" placeholder="最低Diffを入力してください。" isErrors={errors} bind:value={under_diff} />
<Input type="number" placeholder="最高Diffを入力してください。" isErrors={errors} bind:value={over_diff} />
<Button onclick={sendQuery} class="shrink-0" disabled={loading}>
<Button onclick={sendQuery} class="shrink-0 w-24 h-12 flex justify-center items-center" disabled={loading}>
{#if loading}
<div class="animate-spin [animation-duration: 2.2s] mr-2">
<Loader size="1rem" />
<div class="animate-spin [animation-duration: 1.05s]">
<Loader size="1.5rem" />
</div>
{:else}
Pick
{/if}
Pick
</Button>
</div>

Expand Down Expand Up @@ -108,6 +113,20 @@
</div>
</Message>
</div>
{:else if errorMessage}
<div class="mt-4">
<Message variant="error">
<div class="flex flex-col">
<Label class="leading-tight font-medium text-lg mb-1.5">
Failed Picking...
</Label>

<p class="text-base-foreground-default mb-1 text-sm">
{errorMessage}
</p>
</div>
</Message>
</div>
{/if}
</div>
</div>
1 change: 1 addition & 0 deletions frontend/src/style.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@100..900&family=Ubuntu+Sans+Mono:ital,wght@0,400..700;1,400..700&display=swap');
@import "tailwindcss";

@theme {
Expand Down