Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

Commit

Permalink
Feed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
OmegaJak committed Oct 25, 2023
1 parent 58358cd commit 0f249dc
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 18 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ derive-new = "0.5.9"

[dev-dependencies]
actix-http = "3.4.0"
assert_matches = "1.5.0"
16 changes: 8 additions & 8 deletions src/models/feed_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ use crate::database::models::event_item as DBEvent;
#[serde(into = "Base62Id")]
pub struct FeedItemId(pub u64);

#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum CreatorId {
User(UserId),
Organization(OrganizationId),
User { id: UserId },
Organization { id: OrganizationId },
}

#[derive(Serialize, Deserialize)]
Expand All @@ -26,7 +26,7 @@ pub struct FeedItem {
pub time: DateTime<Utc>,
}

#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Debug)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum FeedItemBody {
ProjectCreated {
Expand All @@ -39,10 +39,10 @@ pub enum FeedItemBody {
impl From<crate::database::models::event_item::CreatorId> for CreatorId {
fn from(value: crate::database::models::event_item::CreatorId) -> Self {
match value {
DBEvent::CreatorId::User(user_id) => CreatorId::User(user_id.into()),
DBEvent::CreatorId::Organization(organization_id) => {
CreatorId::Organization(organization_id.into())
}
DBEvent::CreatorId::User(user_id) => CreatorId::User { id: user_id.into() },
DBEvent::CreatorId::Organization(organization_id) => CreatorId::Organization {
id: organization_id.into(),
},
}
}
}
2 changes: 1 addition & 1 deletion src/models/organizations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use super::{
use serde::{Deserialize, Serialize};

/// The ID of a team
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
#[serde(from = "Base62Id")]
#[serde(into = "Base62Id")]
pub struct OrganizationId(pub u64);
Expand Down
2 changes: 1 addition & 1 deletion src/routes/v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ pub fn config(cfg: &mut web::ServiceConfig) {
web::scope("v3")
.wrap(default_cors())
.route("", web::get().to(hello_world))
.configure(users::config)
.configure(oauth::config)
.configure(oauth_clients::config)
.configure(users::config)
.configure(organizations::config),
);
}
Expand Down
3 changes: 2 additions & 1 deletion src/routes/v3/users.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ pub fn config(cfg: &mut web::ServiceConfig) {
cfg.service(
web::scope("user")
.service(user_follow)
.service(user_unfollow),
.service(user_unfollow)
.service(current_user_feed),
);
}

Expand Down
10 changes: 10 additions & 0 deletions tests/common/actix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,13 @@ fn generate_multipart(data: impl IntoIterator<Item = MultipartSegment>) -> (Stri

(boundary, Bytes::from(payload))
}

pub trait TestRequestExtensions {
fn append_auth(self, pat: &str) -> TestRequest;
}

impl TestRequestExtensions for TestRequest {
fn append_auth(self, pat: &str) -> TestRequest {
self.append_header((reqwest::header::AUTHORIZATION, pat))
}
}
11 changes: 8 additions & 3 deletions tests/common/api_v2/organization.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use actix_http::StatusCode;
use actix_web::{
dev::ServiceResponse,
test::{self, TestRequest},
Expand All @@ -6,7 +7,7 @@ use bytes::Bytes;
use labrinth::models::{organizations::Organization, projects::Project};
use serde_json::json;

use crate::common::request_data::ImageData;
use crate::common::{asserts::assert_status, request_data::ImageData};

use super::ApiV2;

Expand Down Expand Up @@ -42,8 +43,7 @@ impl ApiV2 {
pat: &str,
) -> Organization {
let resp = self.get_organization(id_or_title, pat).await;
assert_eq!(resp.status(), 200);
test::read_body_json(resp).await
deser_organization(resp).await
}

pub async fn get_organization_projects(&self, id_or_title: &str, pat: &str) -> ServiceResponse {
Expand Down Expand Up @@ -150,3 +150,8 @@ impl ApiV2 {
self.call(req).await
}
}

pub async fn deser_organization(response: ServiceResponse) -> Organization {
assert_status(&response, StatusCode::OK);
test::read_body_json(response).await
}
2 changes: 2 additions & 0 deletions tests/common/api_v3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use std::rc::Rc;

pub mod oauth;
pub mod oauth_clients;
pub mod organization;
pub mod user;

#[derive(Clone)]
pub struct ApiV3 {
Expand Down
25 changes: 25 additions & 0 deletions tests/common/api_v3/organization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use actix_web::{dev::ServiceResponse, test::TestRequest};

use crate::common::actix::TestRequestExtensions;

use super::ApiV3;

impl ApiV3 {
pub async fn follow_organization(&self, organization_id: &str, pat: &str) -> ServiceResponse {
let req = TestRequest::post()
.uri(&format!("/v3/organization/{}/follow", organization_id))
.append_auth(pat)
.to_request();

self.call(req).await
}

pub async fn unfollow_organization(&self, organization_id: &str, pat: &str) -> ServiceResponse {
let req = TestRequest::delete()
.uri(&format!("/v3/organization/{}/follow", organization_id))
.append_auth(pat)
.to_request();

self.call(req).await
}
}
41 changes: 41 additions & 0 deletions tests/common/api_v3/user.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use actix_http::StatusCode;
use actix_web::{
dev::ServiceResponse,
test::{self, TestRequest},
};
use labrinth::models::feed_item::FeedItem;

use crate::common::{actix::TestRequestExtensions, asserts::assert_status};

use super::ApiV3;

impl ApiV3 {
pub async fn follow_user(&self, user_id: &str, pat: &str) -> ServiceResponse {
let req = TestRequest::post()
.uri(&format!("/v3/user/{}/follow", user_id))
.append_auth(pat)
.to_request();

self.call(req).await
}

pub async fn unfollow_user(&self, user_id: &str, pat: &str) -> ServiceResponse {
let req = TestRequest::delete()
.uri(&format!("/v3/user/{}/follow", user_id))
.append_auth(pat)
.to_request();

self.call(req).await
}

pub async fn get_feed(&self, pat: &str) -> Vec<FeedItem> {
let req = TestRequest::get()
.uri("/v3/user/feed")
.append_auth(pat)
.to_request();
let resp = self.call(req).await;
assert_status(&resp, StatusCode::OK);

test::read_body_json(resp).await
}
}
4 changes: 2 additions & 2 deletions tests/common/dummy_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use super::{
request_data::get_public_project_creation_data,
};

pub const DUMMY_DATA_UPDATE: i64 = 2;
pub const DUMMY_DATA_UPDATE: i64 = 3;

#[allow(dead_code)]
pub const DUMMY_CATEGORIES: &[&str] = &[
Expand Down Expand Up @@ -212,7 +212,7 @@ pub async fn add_project_alpha(test_env: &TestEnvironment) -> (Project, Version)
let (project, versions) = test_env
.v2
.add_public_project(
get_public_project_creation_data("alpha", Some(DummyJarFile::DummyProjectAlpha)),
get_public_project_creation_data("alpha", Some(DummyJarFile::DummyProjectAlpha), None),
USER_USER_PAT,
)
.await;
Expand Down
2 changes: 1 addition & 1 deletion tests/common/permissions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ async fn create_dummy_project(test_env: &TestEnvironment) -> (String, String) {
// Create a very simple project
let slug = generate_random_name("test_project");

let creation_data = request_data::get_public_project_creation_data(&slug, None);
let creation_data = request_data::get_public_project_creation_data(&slug, None, None);
let (project, _) = api.add_public_project(creation_data, ADMIN_USER_PAT).await;
let project_id = project.id.to_string();
let team_id = project.team.to_string();
Expand Down
4 changes: 3 additions & 1 deletion tests/common/request_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct ImageData {
pub fn get_public_project_creation_data(
slug: &str,
version_jar: Option<DummyJarFile>,
organization_id: Option<&str>,
) -> ProjectCreationRequestData {
let initial_versions = if let Some(ref jar) = version_jar {
json!([{
Expand Down Expand Up @@ -51,7 +52,8 @@ pub fn get_public_project_creation_data(
"initial_versions": initial_versions,
"is_draft": is_draft,
"categories": [],
"license_id": "MIT"
"license_id": "MIT",
"organization_id": organization_id
}
);

Expand Down
71 changes: 71 additions & 0 deletions tests/feed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use assert_matches::assert_matches;
use common::{
api_v2::organization::deser_organization,
database::{FRIEND_USER_PAT, USER_USER_ID, USER_USER_PAT},
environment::with_test_environment,
request_data::get_public_project_creation_data,
};
use labrinth::models::feed_item::FeedItemBody;

use crate::common::dummy_data::DummyProjectAlpha;

mod common;

#[actix_rt::test]
async fn user_feed_before_following_user_shows_no_projects() {
with_test_environment(|env| async move {
let feed = env.v3.get_feed(FRIEND_USER_PAT).await;

assert_eq!(feed.len(), 0);
})
.await
}

#[actix_rt::test]
async fn user_feed_after_following_user_shows_previously_created_public_projects() {
with_test_environment(|env| async move {
let DummyProjectAlpha {
project_id: alpha_project_id,
..
} = env.dummy.as_ref().unwrap().project_alpha.clone();
env.v3.follow_user(USER_USER_ID, FRIEND_USER_PAT).await;

let feed = env.v3.get_feed(FRIEND_USER_PAT).await;

assert_eq!(feed.len(), 1);
assert_matches!(
feed[0].body,
FeedItemBody::ProjectCreated { project_id, .. } if project_id.to_string() == alpha_project_id
)
})
.await
}

#[actix_rt::test]
async fn user_feed_when_following_user_that_creates_project_as_org_only_shows_event_when_following_org(
) {
with_test_environment(|env| async move {
let resp = env
.v2
.create_organization("test", "desc", USER_USER_ID)
.await;
let organization = deser_organization(resp).await;
let org_id = organization.id.to_string();
let project_create_data = get_public_project_creation_data("a", None, Some(&org_id));
let (project, _) = env
.v2
.add_public_project(project_create_data, USER_USER_PAT)
.await;

env.v3.follow_user(USER_USER_ID, FRIEND_USER_PAT).await;
let feed = env.v3.get_feed(FRIEND_USER_PAT).await;
assert_eq!(feed.len(), 1);
assert_matches!(feed[0].body, FeedItemBody::ProjectCreated { project_id, .. } if project_id != project.id);

env.v3.follow_organization(&org_id, FRIEND_USER_PAT).await;
let feed = env.v3.get_feed(FRIEND_USER_PAT).await;
assert_eq!(feed.len(), 1);
assert_matches!(feed[0].body, FeedItemBody::ProjectCreated { project_id, .. } if project_id == project.id);
})
.await;
}

0 comments on commit 0f249dc

Please sign in to comment.