@@ -261,6 +261,221 @@ Deno.test("SessionImpl.publish()", async (t) => {
261261 } ) ;
262262} ) ;
263263
264+ Deno . test ( "SessionImpl.getOutbox()" , async ( t ) => {
265+ const kv = new MemoryKvStore ( ) ;
266+ const bot = new BotImpl < void > ( { kv, username : "bot" } ) ;
267+ const ctx = createMockContext ( bot , "https://example.com" ) ;
268+ const session = new SessionImpl ( bot , ctx ) ;
269+
270+ await kv . set (
271+ [ ...bot . kvPrefixes . messages , "01941f29-7c00-7fe8-ab0a-7b593990a3c0" ] ,
272+ {
273+ "@context" : "https://www.w3.org/ns/activitystreams" ,
274+ type : "Create" ,
275+ id : "https://example.com/ap/create/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
276+ actor : "https://example.com/ap/actor/bot" ,
277+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
278+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
279+ object : {
280+ type : "Note" ,
281+ id : "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
282+ attributedTo : "https://example.com/ap/actor/bot" ,
283+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
284+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
285+ content : "Hello, world!" ,
286+ published : "2025-01-01T00:00:00Z" ,
287+ } ,
288+ published : "2025-01-01T00:00:00Z" ,
289+ } ,
290+ ) ;
291+ await kv . set (
292+ [ ...bot . kvPrefixes . messages , "0194244f-d800-7873-8993-ef71ccd47306" ] ,
293+ {
294+ "@context" : "https://www.w3.org/ns/activitystreams" ,
295+ type : "Create" ,
296+ id : "https://example.com/ap/create/0194244f-d800-7873-8993-ef71ccd47306" ,
297+ actor : "https://example.com/ap/actor/bot" ,
298+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
299+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
300+ object : {
301+ type : "Note" ,
302+ id : "https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306" ,
303+ attributedTo : "https://example.com/ap/actor/bot" ,
304+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
305+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
306+ content : "Hello, world!" ,
307+ published : "2025-01-02T00:00:00Z" ,
308+ } ,
309+ published : "2025-01-02T00:00:00Z" ,
310+ } ,
311+ ) ;
312+ await kv . set (
313+ [ ...bot . kvPrefixes . messages , "01942976-3400-7f34-872e-2cbf0f9eeac4" ] ,
314+ {
315+ "@context" : "https://www.w3.org/ns/activitystreams" ,
316+ type : "Create" ,
317+ id : "https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
318+ actor : "https://example.com/ap/actor/bot" ,
319+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
320+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
321+ object : {
322+ type : "Note" ,
323+ id : "https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
324+ attributedTo : "https://example.com/ap/actor/bot" ,
325+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
326+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
327+ content : "Hello, world!" ,
328+ published : "2025-01-03T00:00:00Z" ,
329+ } ,
330+ published : "2025-01-03T00:00:00Z" ,
331+ } ,
332+ ) ;
333+ await kv . set (
334+ [ ...bot . kvPrefixes . messages , "01942e9c-9000-7480-a553-7a6ce737ce14" ] ,
335+ {
336+ "@context" : "https://www.w3.org/ns/activitystreams" ,
337+ type : "Create" ,
338+ id : "https://example.com/ap/create/01942e9c-9000-7480-a553-7a6ce737ce14" ,
339+ actor : "https://example.com/ap/actor/bot" ,
340+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
341+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
342+ object : {
343+ type : "Note" ,
344+ id : "https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14" ,
345+ attributedTo : "https://example.com/ap/actor/bot" ,
346+ to : [ "https://example.com/ap/actor/bot/followers" ] ,
347+ cc : [ "https://www.w3.org/ns/activitystreams#Public" ] ,
348+ content : "Hello, world!" ,
349+ published : "2025-01-04T00:00:00Z" ,
350+ } ,
351+ published : "2025-01-04T00:00:00Z" ,
352+ } ,
353+ ) ;
354+ await kv . set (
355+ bot . kvPrefixes . messages ,
356+ [
357+ "01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
358+ "0194244f-d800-7873-8993-ef71ccd47306" ,
359+ "01942976-3400-7f34-872e-2cbf0f9eeac4" ,
360+ "01942e9c-9000-7480-a553-7a6ce737ce14" ,
361+ ] ,
362+ ) ;
363+
364+ await t . step ( "default" , async ( ) => {
365+ const outbox = session . getOutbox ( { order : "oldest" } ) ;
366+ const messages = await Array . fromAsync ( outbox ) ;
367+ assertEquals ( messages . length , 4 ) ;
368+
369+ assertEquals (
370+ messages [ 0 ] . id . href ,
371+ "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
372+ ) ;
373+ assertEquals (
374+ messages [ 0 ] . actor . id ?. href ,
375+ "https://example.com/ap/actor/bot" ,
376+ ) ;
377+ assertEquals ( messages [ 0 ] . visibility , "unlisted" ) ;
378+ assertEquals ( messages [ 0 ] . text , "Hello, world!" ) ;
379+ assertEquals (
380+ messages [ 0 ] . published ,
381+ Temporal . Instant . from ( "2025-01-01T00:00:00Z" ) ,
382+ ) ;
383+
384+ assertEquals (
385+ messages [ 1 ] . id . href ,
386+ "https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306" ,
387+ ) ;
388+ assertEquals (
389+ messages [ 1 ] . actor . id ?. href ,
390+ "https://example.com/ap/actor/bot" ,
391+ ) ;
392+ assertEquals ( messages [ 1 ] . visibility , "unlisted" ) ;
393+ assertEquals ( messages [ 1 ] . text , "Hello, world!" ) ;
394+ assertEquals (
395+ messages [ 1 ] . published ,
396+ Temporal . Instant . from ( "2025-01-02T00:00:00Z" ) ,
397+ ) ;
398+
399+ assertEquals (
400+ messages [ 2 ] . id . href ,
401+ "https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
402+ ) ;
403+ assertEquals (
404+ messages [ 2 ] . actor . id ?. href ,
405+ "https://example.com/ap/actor/bot" ,
406+ ) ;
407+ assertEquals ( messages [ 2 ] . visibility , "unlisted" ) ;
408+ assertEquals ( messages [ 2 ] . text , "Hello, world!" ) ;
409+ assertEquals (
410+ messages [ 2 ] . published ,
411+ Temporal . Instant . from ( "2025-01-03T00:00:00Z" ) ,
412+ ) ;
413+
414+ assertEquals (
415+ messages [ 3 ] . id . href ,
416+ "https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14" ,
417+ ) ;
418+ assertEquals (
419+ messages [ 3 ] . actor . id ?. href ,
420+ "https://example.com/ap/actor/bot" ,
421+ ) ;
422+ assertEquals ( messages [ 3 ] . visibility , "unlisted" ) ;
423+ assertEquals ( messages [ 3 ] . text , "Hello, world!" ) ;
424+ assertEquals (
425+ messages [ 3 ] . published ,
426+ Temporal . Instant . from ( "2025-01-04T00:00:00Z" ) ,
427+ ) ;
428+ } ) ;
429+
430+ await t . step ( "order: 'oldest'" , async ( ) => {
431+ const outbox = session . getOutbox ( { order : "oldest" } ) ;
432+ const messages = await Array . fromAsync ( outbox ) ;
433+ const messageIds = messages . map ( ( msg ) => msg . id . href ) ;
434+ assertEquals ( messageIds , [
435+ "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
436+ "https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306" ,
437+ "https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
438+ "https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14" ,
439+ ] ) ;
440+ } ) ;
441+
442+ await t . step ( "order: 'newest'" , async ( ) => {
443+ const outbox = session . getOutbox ( { order : "newest" } ) ;
444+ const messages = await Array . fromAsync ( outbox ) ;
445+ const messageIds = messages . map ( ( msg ) => msg . id . href ) ;
446+ assertEquals ( messageIds , [
447+ "https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14" ,
448+ "https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
449+ "https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306" ,
450+ "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
451+ ] ) ;
452+ } ) ;
453+
454+ await t . step ( "since" , async ( ) => {
455+ const outbox = session . getOutbox ( {
456+ since : Temporal . Instant . from ( "2025-01-03T00:00:00Z" ) ,
457+ } ) ;
458+ const messages = await Array . fromAsync ( outbox ) ;
459+ const messageIds = messages . map ( ( msg ) => msg . id . href ) ;
460+ assertEquals ( messageIds , [
461+ "https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14" ,
462+ "https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4" ,
463+ ] ) ;
464+ } ) ;
465+
466+ await t . step ( "until" , async ( ) => {
467+ const outbox = session . getOutbox ( {
468+ until : Temporal . Instant . from ( "2025-01-02T00:00:00Z" ) ,
469+ } ) ;
470+ const messages = await Array . fromAsync ( outbox ) ;
471+ const messageIds = messages . map ( ( msg ) => msg . id . href ) ;
472+ assertEquals ( messageIds , [
473+ "https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306" ,
474+ "https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0" ,
475+ ] ) ;
476+ } ) ;
477+ } ) ;
478+
264479export interface SentActivity {
265480 recipients : "followers" | Recipient [ ] ;
266481 activity : Activity ;
0 commit comments