wait for post api test function, better announce activity id

This commit is contained in:
phiresky 2023-09-20 10:46:25 +00:00
parent c25734e4ca
commit 2e7d2d1956
4 changed files with 79 additions and 82 deletions

View file

@ -35,7 +35,7 @@ import {
unfollows,
resolveCommunity,
waitUntil,
delay,
waitForPost,
} from "./shared";
import { PostView } from "lemmy-js-client/dist/types/PostView";
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
@ -82,11 +82,11 @@ test("Create a post", async () => {
expect(postRes.post_view.counts.score).toBe(1);
// Make sure that post is liked on beta
const res = await waitUntil(
() => resolvePost(beta, postRes.post_view.post).catch(e => null),
res => res?.post?.counts.score === 1,
const betaPost = await waitForPost(
beta,
postRes.post_view.post,
res => res?.counts.score === 1,
);
let betaPost = res?.post;
expect(betaPost).toBeDefined();
expect(betaPost?.community.local).toBe(true);
@ -122,12 +122,12 @@ test("Unlike a post", async () => {
expect(unlike2.post_view.counts.score).toBe(0);
// Make sure that post is unliked on beta
const betaPost = (
await waitUntil(
() => resolvePost(beta, postRes.post_view.post),
b => b.post?.counts.score === 0,
)
).post;
const betaPost = await waitForPost(
beta,
postRes.post_view.post,
post => post.counts.score === 0,
);
expect(betaPost).toBeDefined();
expect(betaPost?.community.local).toBe(true);
expect(betaPost?.creator.local).toBe(false);
@ -140,26 +140,16 @@ test("Update a post", async () => {
throw "Missing beta community";
}
let postRes = await createPost(alpha, betaCommunity.community.id);
await waitUntil(
() => resolvePost(beta, postRes.post_view.post),
res => !!res.post,
);
await waitForPost(beta, postRes.post_view.post);
let updatedName = "A jest test federated post, updated";
let updatedPost = await editPost(alpha, postRes.post_view.post);
await waitUntil(
() => resolvePost(beta, postRes.post_view.post),
res => res.post?.post.name === updatedName,
);
expect(updatedPost.post_view.post.name).toBe(updatedName);
expect(updatedPost.post_view.community.local).toBe(false);
expect(updatedPost.post_view.creator.local).toBe(true);
// Make sure that post is updated on beta
let betaPost = (await resolvePost(beta, postRes.post_view.post)).post;
if (!betaPost) {
throw "Missing beta post";
}
let betaPost = await waitForPost(beta, updatedPost.post_view.post);
expect(betaPost.community.local).toBe(true);
expect(betaPost.creator.local).toBe(false);
expect(betaPost.post.name).toBe(updatedName);
@ -223,26 +213,17 @@ test("Lock a post", async () => {
);
let postRes = await createPost(alpha, betaCommunity.community.id);
// wait for federation
await waitUntil(
() => searchPostLocal(beta, postRes.post_view.post),
res => !!res.posts[0],
);
let betaPost1 = await waitForPost(beta, postRes.post_view.post);
// Lock the post
let betaPost1 = (await resolvePost(beta, postRes.post_view.post)).post;
if (!betaPost1) {
throw "Missing beta post1";
}
let lockedPostRes = await lockPost(beta, true, betaPost1.post);
expect(lockedPostRes.post_view.post.locked).toBe(true);
// Make sure that post is locked on alpha
let searchAlpha = await waitUntil(
() => searchPostLocal(alpha, postRes.post_view.post),
res => res.posts[0]?.post.locked,
let alphaPost1 = await waitForPost(
alpha,
postRes.post_view.post,
post => post.post.locked,
);
let alphaPost1 = searchAlpha.posts[0];
expect(alphaPost1.post.locked).toBe(true);
// Try to make a new comment there, on alpha
await expect(createComment(alpha, alphaPost1.post.id)).rejects.toBe("locked");
@ -252,11 +233,11 @@ test("Lock a post", async () => {
expect(unlockedPost.post_view.post.locked).toBe(false);
// Make sure that post is unlocked on alpha
let searchAlpha2 = await waitUntil(
() => searchPostLocal(alpha, postRes.post_view.post),
res => !res.posts[0]?.post.locked,
let alphaPost2 = await waitForPost(
alpha,
postRes.post_view.post,
post => !post.post.locked,
);
let alphaPost2 = searchAlpha2.posts[0];
expect(alphaPost2.community.local).toBe(false);
expect(alphaPost2.creator.local).toBe(true);
expect(alphaPost2.post.locked).toBe(false);
@ -280,21 +261,14 @@ test("Delete a post", async () => {
// Make sure lemmy beta sees post is deleted
// This will be undefined because of the tombstone
await waitUntil(
() => resolvePost(beta, postRes.post_view.post).catch(e => e),
e => e === "couldnt_find_object",
);
await waitForPost(beta, postRes.post_view.post, p => !p);
// Undelete
let undeletedPost = await deletePost(alpha, false, postRes.post_view.post);
// Make sure lemmy beta sees post is undeleted
let betaPost2 = (
await waitUntil(
() => resolvePost(beta, postRes.post_view.post).catch(e => e),
e => e !== "couldnt_find_object",
)
).post;
let betaPost2 = await waitForPost(beta, postRes.post_view.post);
if (!betaPost2) {
throw "Missing beta post 2";
}
@ -354,11 +328,7 @@ test("Remove a post from admin and community on same instance", async () => {
let postRes = await createPost(alpha, betaCommunity.community.id);
expect(postRes.post_view.post).toBeDefined();
// Get the id for beta
let searchBeta = await waitUntil(
() => searchPostLocal(beta, postRes.post_view.post),
res => !!res.posts[0],
);
let betaPost = searchBeta.posts[0];
let betaPost = await waitForPost(beta, postRes.post_view.post);
expect(betaPost).toBeDefined();
// The beta admin removes it (the community lives on beta)
@ -366,24 +336,26 @@ test("Remove a post from admin and community on same instance", async () => {
expect(removePostRes.post_view.post.removed).toBe(true);
// Make sure lemmy alpha sees post is removed
let alphaPost = await waitUntil(
() => getPost(alpha, postRes.post_view.post.id),
p => p.post_view.post.removed,
let alphaPost = await waitForPost(
alpha,
postRes.post_view.post,
p => p.post.removed,
);
expect(alphaPost.post_view.post.removed).toBe(true);
assertPostFederation(alphaPost.post_view, removePostRes.post_view);
expect(alphaPost.post.removed).toBe(true);
assertPostFederation(alphaPost, removePostRes.post_view);
// Undelete
let undeletedPost = await removePost(beta, false, betaPost.post);
expect(undeletedPost.post_view.post.removed).toBe(false);
// Make sure lemmy alpha sees post is undeleted
let alphaPost2 = await waitUntil(
() => getPost(alpha, postRes.post_view.post.id),
p => !p.post_view.post.removed,
let alphaPost2 = await waitForPost(
alpha,
postRes.post_view.post,
p => !p.post.removed,
);
expect(alphaPost2.post_view.post.removed).toBe(false);
assertPostFederation(alphaPost2.post_view, undeletedPost.post_view);
expect(alphaPost2.post.removed).toBe(false);
assertPostFederation(alphaPost2, undeletedPost.post_view);
await unfollowRemotes(alpha);
});
@ -424,11 +396,7 @@ test("Enforce site ban for federated user", async () => {
// alpha makes post in beta community, it federates to beta instance
let postRes1 = await createPost(alpha_user, betaCommunity.community.id);
let searchBeta1 = await waitUntil(
() => searchPostLocal(beta, postRes1.post_view.post),
res => !!res.posts[0],
);
expect(searchBeta1.posts[0]).toBeDefined();
let searchBeta1 = await waitForPost(beta, postRes1.post_view.post);
// ban alpha from its instance
let banAlpha = await banPersonFromSite(
@ -447,7 +415,7 @@ test("Enforce site ban for federated user", async () => {
expect(alphaUserOnBeta1.person?.person.banned).toBe(true);
// existing alpha post should be removed on beta
let searchBeta2 = await getPost(beta, searchBeta1.posts[0].post.id);
let searchBeta2 = await getPost(beta, searchBeta1.post.id);
expect(searchBeta2.post_view.post.removed).toBe(true);
// Unban alpha
@ -461,11 +429,7 @@ test("Enforce site ban for federated user", async () => {
// alpha makes new post in beta community, it federates
let postRes2 = await createPost(alpha_user, betaCommunity.community.id);
let searchBeta3 = await waitUntil(
() => searchPostLocal(beta, postRes2.post_view.post),
e => !!e.posts[0],
);
expect(searchBeta3.posts[0]).toBeDefined();
let searchBeta3 = await waitForPost(beta, postRes2.post_view.post);
let alphaUserOnBeta2 = await resolvePerson(beta, alphaUserActorId);
expect(alphaUserOnBeta2.person?.person.banned).toBe(false);

View file

@ -4,6 +4,7 @@ import {
GetUnreadCount,
GetUnreadCountResponse,
LemmyHttp,
PostView,
} from "lemmy-js-client";
import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
@ -318,6 +319,18 @@ export async function searchPostLocal(
return api.client.search(form);
}
/// wait for a post to appear locally without pulling it
export async function waitForPost(
api: API,
post: Post,
checker: (t: PostView) => boolean = p => !!p,
) {
return waitUntil(
() => searchPostLocal(api, post).then(p => p.posts[0] as PostView),
checker,
);
}
export async function getPost(
api: API,
post_id: number,

View file

@ -1,6 +1,7 @@
use crate::{
activities::{
generate_activity_id,
generate_announce_activity_id,
send_lemmy_activity,
verify_is_public,
verify_person_in_community,
@ -75,16 +76,20 @@ impl AnnounceActivity {
community: &ApubCommunity,
context: &Data<LemmyContext>,
) -> Result<AnnounceActivity, LemmyError> {
let inner_kind = object
.other
.get("type")
.and_then(|e| e.as_str())
.unwrap_or("other");
let id =
generate_announce_activity_id(inner_kind, &context.settings().get_protocol_and_hostname())?;
Ok(AnnounceActivity {
actor: community.id().into(),
to: vec![public()],
object: IdOrNestedObject::NestedObject(object),
cc: vec![community.followers_url.clone().into()],
kind: AnnounceType::Announce,
id: generate_activity_id(
&AnnounceType::Announce,
&context.settings().get_protocol_and_hostname(),
)?,
id,
})
}

View file

@ -28,7 +28,7 @@ use crate::{
use activitypub_federation::{
config::Data,
fetch::object_id::ObjectId,
kinds::public,
kinds::{activity::AnnounceType, public},
protocol::context::WithContext,
traits::{ActivityHandler, Actor},
};
@ -185,6 +185,21 @@ where
Url::parse(&id)
}
/// like generate_activity_id but also add the inner kind for easier debugging
fn generate_announce_activity_id(
inner_kind: &str,
protocol_and_hostname: &str,
) -> Result<Url, ParseError> {
let id = format!(
"{}/activities/{}/{}/{}",
protocol_and_hostname,
AnnounceType::Announce.to_string().to_lowercase(),
inner_kind,
Uuid::new_v4()
);
Url::parse(&id)
}
pub(crate) trait GetActorType {
fn actor_type(&self) -> ActorType;
}