Skip to content

Commit

Permalink
Merge branch 'master' into building-name
Browse files Browse the repository at this point in the history
  • Loading branch information
SamZhang02 authored Jul 16, 2023
2 parents e1f9a31 + 36083d3 commit 6a03290
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 14 deletions.
7 changes: 7 additions & 0 deletions client/src/model/GetCourseWithReviewsPayload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Course } from './Course';
import { Review } from './Review';

export type GetCourseWithReviewsPayload = {
course: Course;
reviews: Review[];
};
21 changes: 8 additions & 13 deletions client/src/pages/CoursePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { useAuth } from '../hooks/useAuth';
import { fetchClient } from '../lib/fetchClient';
import { getCurrentTerms } from '../lib/utils';
import { Course } from '../model/Course';
import { GetCourseWithReviewsPayload } from '../model/GetCourseWithReviewsPayload';
import { Requirements } from '../model/Requirements';
import { Review } from '../model/Review';
import { Loading } from './Loading';
Expand All @@ -40,19 +41,13 @@ export const CoursePage = () => {

useEffect(() => {
fetchClient
.getData<Course>(`/courses/${params.id?.toUpperCase()}`)
.then((data) => setCourse(data))
.catch((err) => console.log(err));
fetchClient
.getData<Review[]>(`/reviews?course_id=${params.id}`)
.then((data) => {
data = data.sort(
(a, b) =>
parseInt(b.timestamp.$date.$numberLong, 10) -
parseInt(a.timestamp.$date.$numberLong, 10)
);
setShowingReviews(data);
setAllReviews(data);
.getData<GetCourseWithReviewsPayload>(
`/courses/${params.id?.toUpperCase()}?with_reviews=true`
)
.then((payload) => {
setCourse(payload.course);
setShowingReviews(payload.reviews);
setAllReviews(payload.reviews);
})
.catch((err) => console.log(err));
}, [params.id, addReviewOpen, editReviewOpen]);
Expand Down
24 changes: 23 additions & 1 deletion src/courses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,34 @@ pub(crate) async fn get_courses(
))
}

#[derive(Debug, Deserialize)]
pub(crate) struct GetCourseParams {
with_reviews: Option<bool>,
}

pub(crate) async fn get_course_by_id(
Path(id): Path<String>,
Query(params): Query<GetCourseParams>,
AppState(state): AppState<State>,
) -> Result<impl IntoResponse> {
Ok(match state.db.find_course_by_id(&id).await? {
Some(course) => (StatusCode::OK, Json(Some(course))),
Some(course) => {
let mut reviews = params
.with_reviews
.unwrap_or(false)
.then_some(state.db.find_reviews_by_course_id(&id).await?);

if let Some(ref mut reviews) = reviews {
reviews.sort_by(|a, b| b.timestamp.cmp(&a.timestamp));

return Ok((
StatusCode::OK,
Json(Some(json!({ "course": course, "reviews": reviews }))),
));
}

(StatusCode::OK, Json(Some(json!(course))))
}
None => (StatusCode::NOT_FOUND, Json(None)),
})
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ use {
rayon::prelude::*,
reqwest::blocking::RequestBuilder,
serde::{Deserialize, Serialize},
serde_json::json,
std::{
collections::HashSet,
env,
Expand Down
71 changes: 71 additions & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ mod tests {
}
}

#[derive(Debug, Deserialize, Serialize)]
pub(crate) struct GetCourseWithReviewsPayload {
pub(crate) course: Course,
pub(crate) reviews: Vec<Review>,
}

#[tokio::test]
async fn courses_route_works() {
let TestContext { db, app, .. } = TestContext::new().await;
Expand Down Expand Up @@ -326,6 +332,71 @@ mod tests {
);
}

#[tokio::test]
async fn can_get_course_with_reviews() {
let TestContext {
db,
mut app,
session_store,
..
} = TestContext::new().await;

db.initialize(InitializeOptions {
source: seed(),
..Default::default()
})
.await
.unwrap();

let cookie = mock_login(session_store, "test", "[email protected]").await;

let review = json!({
"content": "test",
"course_id": "MATH240",
"instructors": ["Adrian Roshan Vetta"],
"rating": 5,
"difficulty": 5
})
.to_string();

let response = app
.call(
Request::builder()
.method(http::Method::POST)
.header("Cookie", cookie.clone())
.header("Content-Type", "application/json")
.uri("/api/reviews")
.body(Body::from(review))
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::OK);
assert_eq!(db.find_reviews_by_user_id("test").await.unwrap().len(), 1);

let response = app
.call(
Request::builder()
.uri("/api/courses/MATH240?with_reviews=true")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();

assert_eq!(response.status(), StatusCode::OK);

let payload = response.convert::<GetCourseWithReviewsPayload>().await;

assert_eq!(
payload.course,
db.find_course_by_id("MATH240").await.unwrap().unwrap()
);

assert_eq!(payload.reviews.len(), 1);
}

#[tokio::test]
async fn course_by_id_invalid_course_code() {
let TestContext { db, app, .. } = TestContext::new().await;
Expand Down

0 comments on commit 6a03290

Please sign in to comment.