@@ -17,6 +17,7 @@ import { createAccount } from "../../tests/helpers/oauth";
1717import db from "../db" ;
1818import { accounts , follows , instances , posts , timelinePosts } from "../schema" ;
1919import type { Uuid } from "../uuid" ;
20+ import { toTemporalInstant } from "./date" ;
2021import { onPostShared } from "./inbox" ;
2122import { persistPost , persistSharingPost , toObject } from "./post" ;
2223
@@ -381,6 +382,102 @@ describe("persistPost", () => {
381382 expect ( post ?. repliesCount ) . toBe ( 3 ) ;
382383 expect ( jobs . map ( ( job ) => job . repliesIri ) ) . toEqual ( [ repliesIri ] ) ;
383384 } ) ;
385+
386+ it ( "ignores posts with a published date more than 12 hours in the future" , async ( ) => {
387+ expect . assertions ( 3 ) ;
388+ const author = await seedRemoteAccount ( "author" ) ;
389+ const futureDate = new Date ( Date . now ( ) + 13 * 60 * 60 * 1000 ) ;
390+ const iri = "https://remote.test/@author/posts/future" ;
391+
392+ const result = await persistPost (
393+ db ,
394+ new Note ( {
395+ id : new URL ( iri ) ,
396+ attribution : createPerson ( author ) ,
397+ content : "<p>From the future</p>" ,
398+ to : PUBLIC_COLLECTION ,
399+ published : toTemporalInstant ( futureDate ) ,
400+ } ) ,
401+ "https://hollo.test" ,
402+ { account : author } ,
403+ ) ;
404+ const row = await db . query . posts . findFirst ( { where : eq ( posts . iri , iri ) } ) ;
405+ const timelineRows = await db . query . timelinePosts . findMany ( ) ;
406+
407+ expect ( result ) . toBeNull ( ) ;
408+ expect ( row ) . toBeUndefined ( ) ;
409+ expect ( timelineRows ) . toHaveLength ( 0 ) ;
410+ } ) ;
411+
412+ it ( "ignores posts with an updated date more than 12 hours in the future" , async ( ) => {
413+ expect . assertions ( 3 ) ;
414+ const author = await seedRemoteAccount ( "author" ) ;
415+ const futureDate = new Date ( Date . now ( ) + 13 * 60 * 60 * 1000 ) ;
416+ const iri = "https://remote.test/@author/posts/future-updated" ;
417+
418+ const result = await persistPost (
419+ db ,
420+ new Note ( {
421+ id : new URL ( iri ) ,
422+ attribution : createPerson ( author ) ,
423+ content : "<p>Updated in the future</p>" ,
424+ to : PUBLIC_COLLECTION ,
425+ updated : toTemporalInstant ( futureDate ) ,
426+ } ) ,
427+ "https://hollo.test" ,
428+ { account : author } ,
429+ ) ;
430+ const row = await db . query . posts . findFirst ( { where : eq ( posts . iri , iri ) } ) ;
431+ const timelineRows = await db . query . timelinePosts . findMany ( ) ;
432+
433+ expect ( result ) . toBeNull ( ) ;
434+ expect ( row ) . toBeUndefined ( ) ;
435+ expect ( timelineRows ) . toHaveLength ( 0 ) ;
436+ } ) ;
437+
438+ it ( "accepts posts with a published date slightly in the future (within 12 hours)" , async ( ) => {
439+ expect . assertions ( 1 ) ;
440+ const author = await seedRemoteAccount ( "author" ) ;
441+ const slightlyFutureDate = new Date ( Date . now ( ) + 11 * 60 * 60 * 1000 ) ;
442+
443+ const result = await persistPost (
444+ db ,
445+ new Note ( {
446+ id : new URL ( "https://remote.test/@author/posts/near-future" ) ,
447+ attribution : createPerson ( author ) ,
448+ content : "<p>Slightly future</p>" ,
449+ to : PUBLIC_COLLECTION ,
450+ published : toTemporalInstant ( slightlyFutureDate ) ,
451+ } ) ,
452+ "https://hollo.test" ,
453+ { account : author } ,
454+ ) ;
455+
456+ expect ( result ) . not . toBeNull ( ) ;
457+ } ) ;
458+
459+ it ( "accepts posts with a pre-epoch timestamp without crashing" , async ( ) => {
460+ expect . assertions ( 2 ) ;
461+ const author = await seedRemoteAccount ( "author" ) ;
462+ // 1963-11-22, before Unix epoch (1970-01-01)
463+ const preEpochDate = new Date ( "1963-11-22T12:30:00Z" ) ;
464+
465+ const result = await persistPost (
466+ db ,
467+ new Note ( {
468+ id : new URL ( "https://remote.test/@author/posts/old-post" ) ,
469+ attribution : createPerson ( author ) ,
470+ content : "<p>A very old post</p>" ,
471+ to : PUBLIC_COLLECTION ,
472+ published : toTemporalInstant ( preEpochDate ) ,
473+ } ) ,
474+ "https://hollo.test" ,
475+ { account : author } ,
476+ ) ;
477+
478+ expect ( result ) . not . toBeNull ( ) ;
479+ expect ( result ?. published ) . toEqual ( preEpochDate ) ;
480+ } ) ;
384481} ) ;
385482
386483describe ( "toObject" , ( ) => {
0 commit comments