Skip to content

Commit 91c5290

Browse files
committed
Merge branch 'develop'
2 parents 6105628 + 541e494 commit 91c5290

File tree

84 files changed

+2500
-550
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+2500
-550
lines changed

cloud/firestore/firestore.default.rules

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,19 @@ service cloud.firestore {
5252
allow read: if true;
5353
allow write: if false;
5454
}
55+
match /talksStats-allInOne/self {
56+
allow read: if true;
57+
allow write: if false;
58+
}
5559

5660
match /organizer-space/{secretOrganizerToken} {
5761
allow get: if true;
5862
allow list, write: if false;
5963

60-
match /ratings/self {
64+
match /ratings/{talkId} {
65+
allow read, write: if false;
66+
}
67+
match /daily-ratings/{dayIf} {
6168
allow read, write: if false;
6269
}
6370
}
@@ -100,6 +107,7 @@ service cloud.firestore {
100107
allow get, list, create, update: if iAm(userId);
101108
allow delete: if false;
102109

110+
// TODO: Remove it once Devoxx BE is over
103111
match /__computed/self {
104112
allow get: if true;
105113
allow list, write: if false;

cloud/firestore/firestore.default.rules.spec.ts

Lines changed: 56 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ beforeAll(async () => {
3535
adminFirestore.doc('/users/alice/tokens-wallet/self').set({ publicUserToken: '00d8b3b4-ec51-4694-865c-5e9d0f542e41' }),
3636
adminFirestore.doc('/users/alice/preferences/self').set({ pinnedEventIds: [] }),
3737
adminFirestore.doc('/users/alice/events/an-event').set({}),
38-
adminFirestore.doc('/users/alice/events/an-event/__computed/self').set({ favoritedTalkIds: [] }),
3938
adminFirestore.doc('/users/alice/events/an-event/talksNotes/12345').set({ note: { isFavorite: true } }),
4039
adminFirestore.doc('/users/alice/events/an-event/days/monday').set({ }),
4140
adminFirestore.doc('/users/alice/events/an-event/days/monday/feedbacks/self').set({ dayId: 'monday', feedbacks: [] }),
@@ -44,7 +43,6 @@ beforeAll(async () => {
4443
adminFirestore.doc('/users/fred/tokens-wallet/self').set({ publicUserToken: 'c808ad21-af33-4e20-a6f8-89adc4d14d75' }),
4544
adminFirestore.doc('/users/fred/preferences/self').set({ pinnedEventIds: [] }),
4645
adminFirestore.doc('/users/fred/events/an-event').set({}),
47-
adminFirestore.doc('/users/fred/events/an-event/__computed/self').set({ favoritedTalkIds: [] }),
4846
adminFirestore.doc('/users/fred/events/an-event/talksNotes/12345').set({ note: { isFavorite: true } }),
4947
adminFirestore.doc('/users/fred/events/an-event/days/monday').set({ }),
5048
adminFirestore.doc('/users/fred/events/an-event/days/monday/feedbacks/self').set({ dayId: 'monday', feedbacks: [] }),
@@ -56,9 +54,11 @@ beforeAll(async () => {
5654

5755
adminFirestore.doc('/events/an-event').set({ title: `A super event` }),
5856
adminFirestore.doc('/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472').set({ organizerSecretToken: '6c902c52-9c6d-4d54-b6f2-20814d2f8472' }),
59-
adminFirestore.doc('/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/self').set({ }),
57+
adminFirestore.doc('/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/12345').set({ }),
58+
adminFirestore.doc('/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings/monday').set({ }),
6059
adminFirestore.doc('/events/an-event/days/monday').set({ day: 'monday', timeSlots: [] }),
6160
adminFirestore.doc('/events/an-event/event-descriptor/self').set({ title: `A super event` }),
61+
adminFirestore.doc('/events/an-event/talksStats-allInOne/self').set({ "12345": { id: `12345`, totalFavoritesCount: 0 } }),
6262
adminFirestore.doc('/events/an-event/talksStats/12345').set({ id: `12345`, totalFavoritesCount: 0 }),
6363
adminFirestore.doc('/events/an-event/last-updates/self').set({ favorites: '2023-09-01T00:00:00Z' }),
6464
adminFirestore.doc('/events/an-event/talks/1234').set({ id: '1234', title: 'A super talk' }),
@@ -72,7 +72,6 @@ afterAll(async () => {
7272
adminFirestore.doc(`/users/alice/events/an-event/days/monday/feedbacks/self`).delete(),
7373
adminFirestore.doc(`/users/alice/events/an-event/days/monday`).delete(),
7474
adminFirestore.doc(`/users/alice/events/an-event/talksNotes/12345`).delete(),
75-
adminFirestore.doc('/users/alice/events/an-event/__computed/self').delete(),
7675
adminFirestore.doc(`/users/alice/events/an-event`).delete(),
7776
adminFirestore.doc(`/users/alice/tokens-wallet/self`).delete(),
7877
adminFirestore.doc(`/users/alice/preferences/self`).delete(),
@@ -81,7 +80,6 @@ afterAll(async () => {
8180
adminFirestore.doc(`/users/fred/events/an-event/days/monday/feedbacks/self`).delete(),
8281
adminFirestore.doc(`/users/fred/events/an-event/days/monday`).delete(),
8382
adminFirestore.doc(`/users/fred/events/an-event/talksNotes/12345`).delete(),
84-
adminFirestore.doc('/users/fred/events/an-event/__computed/self').delete(),
8583
adminFirestore.doc(`/users/fred/events/an-event`).delete(),
8684
adminFirestore.doc(`/users/fred/tokens-wallet/self`).delete(),
8785
adminFirestore.doc(`/users/fred/preferences/self`).delete(),
@@ -96,10 +94,12 @@ afterAll(async () => {
9694
adminFirestore.doc(`/events/an-event/talks/1234/feedbacks-access/1f0b405a-c3ba-46df-8d02-cce03bc34e5d`).delete(),
9795
adminFirestore.doc(`/events/an-event/talks/1234`).delete(),
9896
adminFirestore.doc(`/events/an-event/last-updates/self`).delete(),
97+
adminFirestore.doc(`/events/an-event/talksStats-allInOne/self`).delete(),
9998
adminFirestore.doc(`/events/an-event/talksStats/12345`).delete(),
10099
adminFirestore.doc(`/events/an-event/event-descriptor/self`).delete(),
101100
adminFirestore.doc(`/events/an-event/days/monday`).delete(),
102-
adminFirestore.doc(`/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/self`).delete(),
101+
adminFirestore.doc(`/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings/monday`).delete(),
102+
adminFirestore.doc(`/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/12345`).delete(),
103103
adminFirestore.doc(`/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472`).delete(),
104104
adminFirestore.doc(`/events/an-event`).delete(),
105105
]);
@@ -302,52 +302,6 @@ const COLLECTIONS: CollectionDescriptor[] = [{
302302
})
303303
}
304304
}
305-
}, {
306-
name: "/users/{userId}/events/{eventId}/__computed",
307-
aroundTests: (userContext: UserContext) => match(userContext)
308-
.with({ name: "unauthenticated user" }, () => ({
309-
beforeEach: [],
310-
afterEach: [],
311-
}))
312-
.with({ name: "fred user" }, () => ({
313-
beforeEach: [],
314-
afterEach: [],
315-
})).run(),
316-
tests: (userContext: UserContext) => {
317-
it(`As ${userContext.name}, I should not be able to LIST another user events' computed infos`, async () => {
318-
await assertFails(getDocs(collection(userContext.context().firestore(), '/users/alice/events/an-event/__computed')));
319-
})
320-
it(`As ${userContext.name}, I should be able to GET another user events' computed infos`, async () => {
321-
await assertSucceeds(getDoc(doc(userContext.context().firestore(), '/users/alice/events/an-event/__computed/self')));
322-
})
323-
it(`As ${userContext.name}, I should not be able to CREATE another user's events' computed infos`, async () => {
324-
await assertFails(setDoc(doc(userContext.context().firestore(), '/users/alice/events/an-event/__computed/self'), { favoritedTalkIds: [] }));
325-
})
326-
it(`As ${userContext.name}, I should not be able to UPDATE another user's events' computed infos`, async () => {
327-
await assertFails(updateDoc(doc(userContext.context().firestore(), '/users/alice/events/an-event/__computed/self'), { favoritedTalkIds: ['1'] }));
328-
})
329-
it(`As ${userContext.name}, I should not be able to DELETE another user's events' computed infos`, async () => {
330-
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/users/alice/events/an-event/__computed/self')));
331-
})
332-
333-
if(userContext.name === 'fred user') {
334-
it(`As ${userContext.name}, I shoud not be able to LIST my user's events' computed infos`, async () => {
335-
await assertFails(getDocs(collection(userContext.context().firestore(), '/users/fred/events/an-event/__computed')));
336-
})
337-
it(`As ${userContext.name}, I shoud be able to GET my user's events' computed infos`, async () => {
338-
await assertSucceeds(getDoc(doc(userContext.context().firestore(), '/users/fred/events/an-event/__computed/self')));
339-
})
340-
it(`As ${userContext.name}, I shoud not be able to CREATE my user's events' computed infos`, async () => {
341-
await assertFails(setDoc(doc(userContext.context().firestore(), '/users/fred/events/an-event/__computed/self'), { favoritedTalkIds: [] }));
342-
})
343-
it(`As ${userContext.name}, I should not be able to UPDATE my user's events' computed infos`, async () => {
344-
await assertFails(updateDoc(doc(userContext.context().firestore(), '/users/fred/events/an-event/__computed/self'), { favoritedTalkIds: ['1'] }))
345-
})
346-
it(`As ${userContext.name}, I should not be able to DELETE my user's events' computed infos`, async () => {
347-
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/users/fred/events/an-event/__computed/self')));
348-
})
349-
}
350-
}
351305
}, {
352306
name: "/users/{userId}/events/{eventId}/talksNotes",
353307
aroundTests: (userContext: UserContext) => match(userContext)
@@ -678,6 +632,29 @@ const COLLECTIONS: CollectionDescriptor[] = [{
678632
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/events/an-event/talksStats/12345')));
679633
})
680634
}
635+
}, {
636+
name: "/events/{eventId}/talksStats-allInOne",
637+
aroundTests: (userContext: UserContext) => ({
638+
beforeEach: [],
639+
afterEach: [],
640+
}),
641+
tests: (userContext: UserContext) => {
642+
it(`As ${userContext.name}, I should be able to LIST events' all-in-one talks stats`, async () => {
643+
await assertFails(getDocs(collection(userContext.context().firestore(), '/events/an-event/talksStats-allInOne')));
644+
})
645+
it(`As ${userContext.name}, I should be able to GET events' all-in-one talks stats`, async () => {
646+
await assertSucceeds(getDoc(doc(userContext.context().firestore(), '/events/an-event/talksStats-allInOne/self')));
647+
})
648+
it(`As ${userContext.name}, I should not be able to CREATE events' all-in-one talks stats`, async () => {
649+
await assertFails(setDoc(doc(userContext.context().firestore(), '/events/another-event/talksStats-allInOne/self'), { "23456": { id: `23456`, totalFavoritesCount: 0 } }));
650+
})
651+
it(`As ${userContext.name}, I should not be able to UPDATE events' all-in-one talks stats`, async () => {
652+
await assertFails(updateDoc(doc(userContext.context().firestore(), '/events/an-event/talksStats-allInOne/self'), { "12345": { id: `12345`, totalFavoritesCount: 1 } }));
653+
})
654+
it(`As ${userContext.name}, I should not be able to DELETE events' all-in-one talks stats`, async () => {
655+
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/events/an-event/talksStats-allInOne/self')));
656+
})
657+
}
681658
}, {
682659
name: "/events/{eventId}/organizer-space",
683660
aroundTests: (userContext: UserContext) => ({
@@ -712,16 +689,39 @@ const COLLECTIONS: CollectionDescriptor[] = [{
712689
await assertFails(getDocs(collection(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings')));
713690
})
714691
it(`As ${userContext.name}, I should not be able to GET events' organizer space ratings`, async () => {
715-
await assertFails(getDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/self')));
692+
await assertFails(getDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/12345')));
716693
})
717694
it(`As ${userContext.name}, I should not be able to CREATE events' organizer space ratings`, async () => {
718-
await assertFails(setDoc(doc(userContext.context().firestore(), '/events/another-event/organizer-space/d05d6d61-53c4-496c-9269-795a30b70443/ratings/self'), { }));
695+
await assertFails(setDoc(doc(userContext.context().firestore(), '/events/another-event/organizer-space/d05d6d61-53c4-496c-9269-795a30b70443/ratings/23456'), { }));
719696
})
720697
it(`As ${userContext.name}, I should not be able to UPDATE events' organizer space ratings`, async () => {
721-
await assertFails(updateDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/self'), { "12345": {} }));
698+
await assertFails(updateDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/12345'), { "12345": {} }));
722699
})
723700
it(`As ${userContext.name}, I should not be able to DELETE events' organizer space ratings`, async () => {
724-
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/self')));
701+
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/ratings/12345')));
702+
})
703+
}
704+
}, {
705+
name: "/events/{eventId}/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings",
706+
aroundTests: (userContext: UserContext) => ({
707+
beforeEach: [],
708+
afterEach: [],
709+
}),
710+
tests: (userContext: UserContext) => {
711+
it(`As ${userContext.name}, I should not be able to LIST events' organizer space daily ratings`, async () => {
712+
await assertFails(getDocs(collection(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings')));
713+
})
714+
it(`As ${userContext.name}, I should not be able to GET events' organizer space daily ratings`, async () => {
715+
await assertFails(getDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings/monday')));
716+
})
717+
it(`As ${userContext.name}, I should not be able to CREATE events' organizer space daily ratings`, async () => {
718+
await assertFails(setDoc(doc(userContext.context().firestore(), '/events/another-event/organizer-space/d05d6d61-53c4-496c-9269-795a30b70443/daily-ratings/tuesday'), { }));
719+
})
720+
it(`As ${userContext.name}, I should not be able to UPDATE events' organizer space daily ratings`, async () => {
721+
await assertFails(updateDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings/monday'), { }));
722+
})
723+
it(`As ${userContext.name}, I should not be able to DELETE events' organizer space daily ratings`, async () => {
724+
await assertFails(deleteDoc(doc(userContext.context().firestore(), '/events/an-event/organizer-space/6c902c52-9c6d-4d54-b6f2-20814d2f8472/daily-ratings/monday')));
725725
})
726726
}
727727
}, {

cloud/functions/src/crawlers/crawl.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ const crawlAll = async function(criteria: CrawlCriteria) {
112112
durationInSeconds: start.until(end).total('seconds')
113113
}
114114
}catch(e: any) {
115+
console.error(`Error during crawler with id ${crawlerDescriptor.id}:`, e);
115116
throw new Error(`Error during crawler with id ${crawlerDescriptor.id}: ${e?.toString()}`)
116-
throw e;
117117
}
118118
}))
119119
};
@@ -123,7 +123,7 @@ const saveEvent = async function(event: FullEvent) {
123123

124124
await db.collection("events").doc(event.id).set(event.info)
125125

126-
const firestoreEvent = await db.collection("events").doc(event.id);
126+
const firestoreEvent = db.collection("events").doc(event.id);
127127
const organizerSpaceEntries = await firestoreEvent
128128
.collection('organizer-space')
129129
.listDocuments();
@@ -138,7 +138,13 @@ const saveEvent = async function(event: FullEvent) {
138138

139139
await Promise.all([
140140
firestoreEvent.collection('organizer-space').doc(organizerSecretToken).set(organizerSpaceContent),
141-
firestoreEvent.collection('organizer-space').doc(organizerSecretToken).collection('ratings').doc('self').create({}),
141+
...event.talks.map(async talk => {
142+
const talkFeedbacksDoc = db.doc(`events/${event.id}/organizer-space/${organizerSecretToken}/ratings/${talk.id}`)
143+
const talkFeedbacks = await talkFeedbacksDoc.get();
144+
if(!talkFeedbacks.exists) {
145+
await talkFeedbacksDoc.create({});
146+
}
147+
})
142148
])
143149
return {organizerSecretToken, organizerSpaceContent};
144150
}).with(1, async () => {

0 commit comments

Comments
 (0)