Fetch subscription data using 'subscriptions.info' API (#8368)

* Fetch subscription data using 'subscriptions.info' API

* use getByDocumentId

* throw 404

* unnecessary notfound error
This commit is contained in:
Hemachandar
2025-02-11 08:02:51 +05:30
committed by GitHub
parent 6ecf9ca9c3
commit c81802b3bb
6 changed files with 60 additions and 9 deletions
+1 -1
View File
@@ -358,7 +358,7 @@ export const unsubscribeDocument = createAction({
const document = stores.documents.get(activeDocumentId);
await document?.unsubscribe(currentUserId);
await document?.unsubscribe();
toast.success(t("Unsubscribed from document notifications"));
},
+1 -1
View File
@@ -96,7 +96,7 @@ const MenuTrigger: React.FC<MenuTriggerProps> = ({ label, onTrigger }) => {
const { model: document, menuState } = useMenuContext<Document>();
const { data, loading, error, request } = useRequest(() =>
subscriptions.fetchPage({
subscriptions.fetchOne({
documentId: document.id,
event: "documents.update",
})
+2 -4
View File
@@ -307,9 +307,7 @@ export default class Document extends ArchivableModel implements Searchable {
*/
@computed
get isSubscribed(): boolean {
return !!this.store.rootStore.subscriptions.orderedData.find(
(subscription) => subscription.documentId === this.id
);
return !!this.store.rootStore.subscriptions.getByDocumentId(this.id);
}
/**
@@ -501,7 +499,7 @@ export default class Document extends ArchivableModel implements Searchable {
* @returns A promise that resolves when the subscription is destroyed.
*/
@action
unsubscribe = (userId: string) => this.store.unsubscribe(userId, this);
unsubscribe = () => this.store.unsubscribe(this);
@action
view = () => {
+3 -3
View File
@@ -816,9 +816,9 @@ export default class DocumentsStore extends Store<Document> {
event: "documents.update",
});
unsubscribe = (userId: string, document: Document) => {
const subscription = this.rootStore.subscriptions.orderedData.find(
(s) => s.documentId === document.id && s.userId === userId
unsubscribe = (document: Document) => {
const subscription = this.rootStore.subscriptions.getByDocumentId(
document.id
);
return subscription?.delete();
+34
View File
@@ -1,4 +1,8 @@
import invariant from "invariant";
import { action } from "mobx";
import Subscription from "~/models/Subscription";
import { client } from "~/utils/ApiClient";
import { AuthorizationError, NotFoundError } from "~/utils/errors";
import RootStore from "./RootStore";
import Store, { RPCAction } from "./base/Store";
@@ -8,4 +12,34 @@ export default class SubscriptionsStore extends Store<Subscription> {
constructor(rootStore: RootStore) {
super(rootStore, Subscription);
}
@action
async fetchOne({ documentId, event }: { documentId: string; event: string }) {
const subscription = this.getByDocumentId(documentId);
if (subscription) {
return subscription;
}
this.isFetching = true;
try {
const res = await client.post(`/${this.apiEndpoint}.info`, {
documentId,
event,
});
invariant(res?.data, "Data should be available");
return this.add(res.data);
} catch (err) {
if (err instanceof AuthorizationError || err instanceof NotFoundError) {
return;
}
throw err;
} finally {
this.isFetching = false;
}
}
getByDocumentId = (documentId: string): Subscription | undefined =>
this.find({ documentId });
}
@@ -202,6 +202,25 @@ describe("#subscriptions.info", () => {
expect(response0.data.documentId).toEqual(document0.id);
});
it("should throw 404 if no subscription found", async () => {
const author = await buildUser();
const subscriber = await buildUser({ teamId: author.teamId });
const document = await buildDocument({
userId: author.id,
teamId: author.teamId,
});
const res = await server.post("/api/subscriptions.info", {
body: {
token: subscriber.getJwtToken(),
documentId: document.id,
event: "documents.update",
},
});
expect(res.status).toEqual(404);
});
it("should not allow outsiders to gain info about a subscription", async () => {
const creator = await buildUser();
const subscriber = await buildUser({ teamId: creator.teamId });