mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-22 20:31:19 +00:00
fix tests
This commit is contained in:
parent
77cebd3d58
commit
637eb5162c
6 changed files with 76 additions and 107 deletions
5
Cargo.lock
generated
5
Cargo.lock
generated
|
@ -10,9 +10,8 @@ checksum = "8f27d075294830fcab6f66e320dab524bc6d048f4a151698e153205559113772"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "activitypub_federation"
|
name = "activitypub_federation"
|
||||||
version = "0.6.0-alpha2"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/LemmyNet/activitypub-federation-rust.git?branch=sign-request#2b5ff07134347c9798a56d1cf4b87054d3bf263f"
|
||||||
checksum = "4877d467ddf2fac85e9ee33aba6f2560df14125b8bfa864f85ab40e9b87753a9"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitystreams-kinds",
|
"activitystreams-kinds",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
|
|
@ -94,7 +94,7 @@ lemmy_db_views = { version = "=0.19.6-beta.7", path = "./crates/db_views" }
|
||||||
lemmy_db_views_actor = { version = "=0.19.6-beta.7", path = "./crates/db_views_actor" }
|
lemmy_db_views_actor = { version = "=0.19.6-beta.7", path = "./crates/db_views_actor" }
|
||||||
lemmy_db_views_moderator = { version = "=0.19.6-beta.7", path = "./crates/db_views_moderator" }
|
lemmy_db_views_moderator = { version = "=0.19.6-beta.7", path = "./crates/db_views_moderator" }
|
||||||
lemmy_federate = { version = "=0.19.6-beta.7", path = "./crates/federate" }
|
lemmy_federate = { version = "=0.19.6-beta.7", path = "./crates/federate" }
|
||||||
activitypub_federation = { version = "0.6.0-alpha2", default-features = false, features = [
|
activitypub_federation = { git = "https://github.com/LemmyNet/activitypub-federation-rust.git", branch = "sign-request", default-features = false, features = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
] }
|
] }
|
||||||
diesel = "2.1.6"
|
diesel = "2.1.6"
|
||||||
|
|
|
@ -11,7 +11,7 @@ killall -s1 lemmy_server || true
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pnpm i
|
pnpm i
|
||||||
pnpm api-test-private-community || true
|
pnpm api-test || true
|
||||||
|
|
||||||
killall -s1 lemmy_server || true
|
killall -s1 lemmy_server || true
|
||||||
killall -s1 pict-rs || true
|
killall -s1 pict-rs || true
|
||||||
|
|
|
@ -310,7 +310,7 @@ test("Fetch remote content in private community", async () => {
|
||||||
p => p?.comment?.comment.id != undefined,
|
p => p?.comment?.comment.id != undefined,
|
||||||
);
|
);
|
||||||
|
|
||||||
// create gamma user and follow community
|
// create gamma user
|
||||||
const gammaCommunityId = (
|
const gammaCommunityId = (
|
||||||
await resolveCommunity(gamma, community.community_view.community.actor_id)
|
await resolveCommunity(gamma, community.community_view.community.actor_id)
|
||||||
).community!.community.id;
|
).community!.community.id;
|
||||||
|
@ -318,6 +318,12 @@ test("Fetch remote content in private community", async () => {
|
||||||
community_id: gammaCommunityId,
|
community_id: gammaCommunityId,
|
||||||
follow: true,
|
follow: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// cannot fetch post yet
|
||||||
|
await expect(resolvePost(gamma, post.post_view.post)).rejects.toStrictEqual(
|
||||||
|
Error("not_found"),
|
||||||
|
);
|
||||||
|
// follow community and approve
|
||||||
await gamma.followCommunity(follow_form);
|
await gamma.followCommunity(follow_form);
|
||||||
await approveFollower(alpha, alphaCommunityId);
|
await approveFollower(alpha, alphaCommunityId);
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::{
|
||||||
objects::community::ApubCommunity,
|
objects::community::ApubCommunity,
|
||||||
};
|
};
|
||||||
use activitypub_federation::{
|
use activitypub_federation::{
|
||||||
|
actix_web::signing_actor,
|
||||||
config::Data,
|
config::Data,
|
||||||
fetch::object_id::ObjectId,
|
fetch::object_id::ObjectId,
|
||||||
traits::{Collection, Object},
|
traits::{Collection, Object},
|
||||||
|
@ -62,32 +63,52 @@ pub(crate) async fn get_apub_community_followers(
|
||||||
info: Path<CommunityPath>,
|
info: Path<CommunityPath>,
|
||||||
query: Query<CommunityIsFollowerQuery>,
|
query: Query<CommunityIsFollowerQuery>,
|
||||||
context: Data<LemmyContext>,
|
context: Data<LemmyContext>,
|
||||||
|
request: HttpRequest,
|
||||||
) -> LemmyResult<HttpResponse> {
|
) -> LemmyResult<HttpResponse> {
|
||||||
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
let community = Community::read_from_name(&mut context.pool(), &info.community_name, false)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(LemmyErrorType::NotFound)?;
|
.ok_or(LemmyErrorType::NotFound)?;
|
||||||
if community.visibility == CommunityVisibility::Private {
|
if let Some(is_follower) = &query.is_follower {
|
||||||
if let Some(is_follower) = &query.is_follower {
|
return check_is_follower(community, is_follower, context, request).await;
|
||||||
// TODO: also check for http sig
|
|
||||||
let instance_id = is_follower.dereference(&context).await?.instance_id();
|
|
||||||
let has_followers = CommunityFollowerView::check_has_followers_from_instance(
|
|
||||||
community.id,
|
|
||||||
instance_id,
|
|
||||||
&mut context.pool(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
return if has_followers.is_ok() {
|
|
||||||
Ok(HttpResponse::Ok().finish())
|
|
||||||
} else {
|
|
||||||
Ok(HttpResponse::NotFound().finish())
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
check_community_fetchable(&community)?;
|
check_community_fetchable(&community)?;
|
||||||
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
let followers = ApubCommunityFollower::read_local(&community.into(), &context).await?;
|
||||||
create_apub_response(&followers)
|
create_apub_response(&followers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if a given actor follows the private community. Returns status 200 if true.
|
||||||
|
async fn check_is_follower(
|
||||||
|
community: Community,
|
||||||
|
is_follower: &ObjectId<SiteOrCommunityOrUser>,
|
||||||
|
context: Data<LemmyContext>,
|
||||||
|
request: HttpRequest,
|
||||||
|
) -> LemmyResult<HttpResponse> {
|
||||||
|
if community.visibility != CommunityVisibility::Private {
|
||||||
|
return Ok(HttpResponse::BadRequest().body("must be a private community"));
|
||||||
|
}
|
||||||
|
// also check for http sig so that followers are not exposed publicly
|
||||||
|
let signing_actor = signing_actor::<SiteOrCommunityOrUser>(&request, None, &context).await?;
|
||||||
|
CommunityFollowerView::check_has_followers_from_instance(
|
||||||
|
community.id,
|
||||||
|
signing_actor.instance_id(),
|
||||||
|
&mut context.pool(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let instance_id = is_follower.dereference(&context).await?.instance_id();
|
||||||
|
let has_followers = CommunityFollowerView::check_has_followers_from_instance(
|
||||||
|
community.id,
|
||||||
|
instance_id,
|
||||||
|
&mut context.pool(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
if has_followers.is_ok() {
|
||||||
|
Ok(HttpResponse::Ok().finish())
|
||||||
|
} else {
|
||||||
|
Ok(HttpResponse::NotFound().finish())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the community outbox, which is populated by a maximum of 20 posts (but no other
|
/// Returns the community outbox, which is populated by a maximum of 20 posts (but no other
|
||||||
/// activities like votes or comments).
|
/// activities like votes or comments).
|
||||||
pub(crate) async fn get_apub_community_outbox(
|
pub(crate) async fn get_apub_community_outbox(
|
||||||
|
@ -145,19 +166,13 @@ pub(crate) mod tests {
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::InstanceId,
|
newtypes::InstanceId,
|
||||||
source::{
|
source::{
|
||||||
community::{
|
community::CommunityInsertForm,
|
||||||
CommunityFollower,
|
|
||||||
CommunityFollowerForm,
|
|
||||||
CommunityFollowerState,
|
|
||||||
CommunityInsertForm,
|
|
||||||
},
|
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
local_site::{LocalSite, LocalSiteInsertForm},
|
local_site::{LocalSite, LocalSiteInsertForm},
|
||||||
local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitInsertForm},
|
local_site_rate_limit::{LocalSiteRateLimit, LocalSiteRateLimitInsertForm},
|
||||||
person::{Person, PersonInsertForm},
|
|
||||||
site::{Site, SiteInsertForm},
|
site::{Site, SiteInsertForm},
|
||||||
},
|
},
|
||||||
traits::{Crud, Followable},
|
traits::Crud,
|
||||||
CommunityVisibility,
|
CommunityVisibility,
|
||||||
};
|
};
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
@ -242,9 +257,13 @@ pub(crate) mod tests {
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(200, res.status());
|
assert_eq!(200, res.status());
|
||||||
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
||||||
let res =
|
let res = get_apub_community_followers(
|
||||||
get_apub_community_followers(path.clone().into(), query, context.reset_request_count())
|
path.clone().into(),
|
||||||
.await?;
|
query,
|
||||||
|
context.reset_request_count(),
|
||||||
|
request.clone(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
assert_eq!(200, res.status());
|
assert_eq!(200, res.status());
|
||||||
let res =
|
let res =
|
||||||
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await?;
|
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await?;
|
||||||
|
@ -282,13 +301,18 @@ pub(crate) mod tests {
|
||||||
.await;
|
.await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
||||||
let res =
|
let res = get_apub_community_followers(
|
||||||
get_apub_community_followers(path.clone().into(), query, context.reset_request_count()).await;
|
path.clone().into(),
|
||||||
|
query,
|
||||||
|
context.reset_request_count(),
|
||||||
|
request.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let res =
|
let res =
|
||||||
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await;
|
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let res = get_apub_community_outbox(path.into(), context.reset_request_count(), request).await;
|
let res = get_apub_community_outbox(path, context.reset_request_count(), request).await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
//Community::delete(&mut context.pool(), community.id).await?;
|
//Community::delete(&mut context.pool(), community.id).await?;
|
||||||
|
@ -317,78 +341,21 @@ pub(crate) mod tests {
|
||||||
.await;
|
.await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
let query = Query(CommunityIsFollowerQuery { is_follower: None });
|
||||||
let res =
|
let res = get_apub_community_followers(
|
||||||
get_apub_community_followers(path.clone().into(), query, context.reset_request_count()).await;
|
path.clone().into(),
|
||||||
|
query,
|
||||||
|
context.reset_request_count(),
|
||||||
|
request.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let res =
|
let res =
|
||||||
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await;
|
get_apub_community_moderators(path.clone().into(), context.reset_request_count()).await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
let res = get_apub_community_outbox(path.into(), context.reset_request_count(), request).await;
|
let res = get_apub_community_outbox(path, context.reset_request_count(), request).await;
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
Instance::delete(&mut context.pool(), instance.id).await?;
|
Instance::delete(&mut context.pool(), instance.id).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
#[serial]
|
|
||||||
async fn test_is_follower() -> LemmyResult<()> {
|
|
||||||
let context = LemmyContext::init_test_context().await;
|
|
||||||
let pool = &mut context.pool();
|
|
||||||
|
|
||||||
// insert local community
|
|
||||||
let local_instance = Instance::read_or_create(pool, "my_domain.tld".to_string()).await?;
|
|
||||||
let community_form = CommunityInsertForm {
|
|
||||||
visibility: Some(CommunityVisibility::Private),
|
|
||||||
..CommunityInsertForm::new(
|
|
||||||
local_instance.id,
|
|
||||||
"test_community_4".to_string(),
|
|
||||||
"nada".to_owned(),
|
|
||||||
"pubkey".to_string(),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let community = Community::create(pool, &community_form).await?;
|
|
||||||
|
|
||||||
// insert remote user
|
|
||||||
let remote_instance = Instance::read_or_create(pool, "other_domain.tld".to_string()).await?;
|
|
||||||
let person_form =
|
|
||||||
PersonInsertForm::new("name".to_string(), "pubkey".to_string(), remote_instance.id);
|
|
||||||
let person = Person::create(pool, &person_form).await?;
|
|
||||||
|
|
||||||
// community has no follower from remote instance, returns error
|
|
||||||
let path: Path<CommunityPath> = CommunityPath {
|
|
||||||
community_name: community.name.clone(),
|
|
||||||
}
|
|
||||||
.into();
|
|
||||||
let query = Query(CommunityIsFollowerQuery {
|
|
||||||
is_follower: Some(person.actor_id.clone().into()),
|
|
||||||
});
|
|
||||||
let res = get_apub_community_followers(
|
|
||||||
path.clone().into(),
|
|
||||||
query.clone().into(),
|
|
||||||
context.reset_request_count(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
assert_eq!(404, res?.status());
|
|
||||||
|
|
||||||
// insert approved follower
|
|
||||||
let follower_form = CommunityFollowerForm {
|
|
||||||
state: Some(CommunityFollowerState::Accepted),
|
|
||||||
..CommunityFollowerForm::new(community.id, person.id)
|
|
||||||
};
|
|
||||||
CommunityFollower::follow(pool, &follower_form).await?;
|
|
||||||
|
|
||||||
// now returns ok
|
|
||||||
let res = get_apub_community_followers(
|
|
||||||
path.clone().into(),
|
|
||||||
query.into(),
|
|
||||||
context.reset_request_count(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
assert_eq!(200, res?.status());
|
|
||||||
|
|
||||||
Instance::delete(pool, local_instance.id).await?;
|
|
||||||
Instance::delete(pool, remote_instance.id).await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,12 +160,9 @@ async fn check_community_content_fetchable(
|
||||||
followers_url
|
followers_url
|
||||||
.query_pairs_mut()
|
.query_pairs_mut()
|
||||||
.append_pair("is_follower", signing_actor.id().as_str());
|
.append_pair("is_follower", signing_actor.id().as_str());
|
||||||
context
|
let req = context.client().get(followers_url.as_str());
|
||||||
.client()
|
let req = context.sign_request(req, Bytes::new()).await?;
|
||||||
.get(followers_url.as_str())
|
context.client().execute(req).await?.error_for_status()?;
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.error_for_status()?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(LemmyErrorType::NotFound.into())
|
Err(LemmyErrorType::NotFound.into())
|
||||||
|
|
Loading…
Reference in a new issue