@fedify/vocab 2.4.0-dev.1567 → 2.4.0-dev.1570

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Temporal } from "@js-temporal/polyfill";
2
2
  globalThis.addEventListener = () => {};
3
- import { A as Person, C as Link, D as Offer, E as Object$1, F as QuoteRequest, H as vocab_exports, I as Reject, M as Proposal, N as Question, O as OrderedCollectionPage, P as QuoteAuthorization, R as Source, S as InteractionRule, T as Note, _ as Follow, b as Intent, c as Create, d as Document, f as Endpoints, g as FeaturedItem, h as FeaturedCollection, i as Announce, j as Place, l as CryptographicKey, m as FeatureRequest, n as Activity, o as Collection, p as FeatureAuthorization, r as Agreement, s as Commitment, t as Accept, u as Delete, w as Measure, x as InteractionPolicy, y as Hashtag, z as Tombstone } from "./vocab-DOHLQ4UQ.mjs";
3
+ import { A as QuoteAuthorization, C as Offer, D as Place, E as Person, F as Tombstone, M as Reject, O as Proposal, P as Source, R as vocab_exports, S as Object$1, _ as InteractionPolicy, b as Measure, c as Create, d as Document, f as Endpoints, g as Intent, h as Hashtag, i as Announce, j as QuoteRequest, k as Question, l as CryptographicKey, n as Activity, o as Collection, p as Follow, r as Agreement, s as Commitment, t as Accept, u as Delete, v as InteractionRule, w as OrderedCollectionPage, x as Note, y as Link } from "./vocab-XnSGFOqq.mjs";
4
4
  import { t as assertInstanceOf } from "./utils-CE8Dk5hm.mjs";
5
5
  import { mockDocumentLoader, test } from "@fedify/fixture";
6
6
  import { deepStrictEqual, notDeepStrictEqual, ok, rejects, throws } from "node:assert/strict";
@@ -53,18 +53,6 @@ const QUOTE_REQUEST_CONTEXT = [
53
53
  }
54
54
  }
55
55
  ];
56
- const FEATURE_CONTEXT = [
57
- "https://www.w3.org/ns/activitystreams",
58
- "https://w3id.org/security/data-integrity/v1",
59
- "https://gotosocial.org/ns",
60
- "https://w3id.org/fep/7aa9"
61
- ];
62
- const FEATURED_COLLECTION_CONTEXT = [...FEATURE_CONTEXT, {
63
- Hashtag: "as:Hashtag",
64
- discoverable: "toot:discoverable",
65
- sensitive: "as:sensitive",
66
- toot: "http://joinmastodon.org/ns#"
67
- }];
68
56
  const DELETE_QUOTE_REQUEST_CONTEXT = [
69
57
  "https://w3id.org/identity/v1",
70
58
  "https://www.w3.org/ns/activitystreams",
@@ -314,662 +302,6 @@ test("Activity.fromJsonLd()", async () => {
314
302
  deepStrictEqual(proofs[0].proofValue, decodeMultibase("z3sXaxjKs4M3BRicwWA9peyNPJvJqxtGsDmpt1jjoHCjgeUf71TRFz56osPSfDErszyLp5Ks1EhYSgpDaNM977Rg2"));
315
303
  deepStrictEqual(proofs[0].created, Temporal.Instant.from("2023-02-24T23:36:38Z"));
316
304
  });
317
- test("fromJsonLd() handles portable ActivityPub IRIs", async () => {
318
- const did = "did:key:z6Mkabc";
319
- const portableActor = `ap://${did}/actor?gateways=https%3A%2F%2Fserver.example`;
320
- const portableObject = `ap://${did}/objects/1?gateways=https%3A%2F%2Fserver.example`;
321
- const uppercasePortableObject = `AP://${did}/objects/1?gateways=https%3A%2F%2Fserver.example`;
322
- const portablePage = `ap://${did}/actor/outbox?page=2`;
323
- const note = await Note.fromJsonLd({
324
- "@context": "https://www.w3.org/ns/activitystreams",
325
- type: "Note",
326
- id: uppercasePortableObject,
327
- attributedTo: `ap+ef61://${encodeURIComponent(did)}/actor?gateways=https%3A%2F%2Fserver.example`
328
- }, {
329
- documentLoader: mockDocumentLoader,
330
- contextLoader: mockDocumentLoader
331
- });
332
- deepStrictEqual(note.id, new URL("ap+ef61://did%3Akey%3Az6Mkabc/objects/1?gateways=https%3A%2F%2Fserver.example"));
333
- deepStrictEqual(note.attributionId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor?gateways=https%3A%2F%2Fserver.example"));
334
- const noteJson = await note.toJsonLd({ contextLoader: mockDocumentLoader });
335
- deepStrictEqual(noteJson.type, "Note");
336
- deepStrictEqual(noteJson.id, "ap+ef61://did:key:z6Mkabc/objects/1?gateways=https%3A%2F%2Fserver.example");
337
- deepStrictEqual(noteJson.attributedTo, "ap+ef61://did:key:z6Mkabc/actor?gateways=https%3A%2F%2Fserver.example");
338
- const activity = await Activity.fromJsonLd({
339
- "@context": "https://www.w3.org/ns/activitystreams",
340
- type: "Create",
341
- actor: portableActor,
342
- object: portableObject
343
- }, {
344
- documentLoader: mockDocumentLoader,
345
- contextLoader: mockDocumentLoader
346
- });
347
- deepStrictEqual(activity.actorId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor?gateways=https%3A%2F%2Fserver.example"));
348
- const activityJson = await activity.toJsonLd({ contextLoader: mockDocumentLoader });
349
- deepStrictEqual(activityJson.type, "Create");
350
- deepStrictEqual(activityJson.actor, "ap+ef61://did:key:z6Mkabc/actor?gateways=https%3A%2F%2Fserver.example");
351
- deepStrictEqual(activityJson.object, "ap+ef61://did:key:z6Mkabc/objects/1?gateways=https%3A%2F%2Fserver.example");
352
- const person = await Person.fromJsonLd({
353
- "@context": "https://www.w3.org/ns/activitystreams",
354
- type: "Person",
355
- inbox: `ap+ef61://${did}/actor/inbox`,
356
- outbox: `ap+ef61://${did}/actor/outbox`
357
- }, {
358
- documentLoader: mockDocumentLoader,
359
- contextLoader: mockDocumentLoader
360
- });
361
- deepStrictEqual(person.inboxId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor/inbox"));
362
- deepStrictEqual(person.outboxId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor/outbox"));
363
- const personJson = await person.toJsonLd({ contextLoader: mockDocumentLoader });
364
- deepStrictEqual(personJson.type, "Person");
365
- deepStrictEqual(personJson.inbox, "ap+ef61://did:key:z6Mkabc/actor/inbox");
366
- deepStrictEqual(personJson.outbox, "ap+ef61://did:key:z6Mkabc/actor/outbox");
367
- const page = await OrderedCollectionPage.fromJsonLd({
368
- "@context": "https://www.w3.org/ns/activitystreams",
369
- type: "OrderedCollectionPage",
370
- next: portablePage,
371
- prev: `ap+ef61://${encodeURIComponent(did)}/actor/outbox?page=1`
372
- }, {
373
- documentLoader: mockDocumentLoader,
374
- contextLoader: mockDocumentLoader
375
- });
376
- deepStrictEqual(page.nextId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor/outbox?page=2"));
377
- deepStrictEqual(page.prevId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor/outbox?page=1"));
378
- const pageJson = await page.toJsonLd({ contextLoader: mockDocumentLoader });
379
- deepStrictEqual(pageJson.type, "OrderedCollectionPage");
380
- deepStrictEqual(pageJson.next, "ap+ef61://did:key:z6Mkabc/actor/outbox?page=2");
381
- deepStrictEqual(pageJson.prev, "ap+ef61://did:key:z6Mkabc/actor/outbox?page=1");
382
- });
383
- test("fromJsonLd() caches text that mentions portable ActivityPub IRIs", async () => {
384
- const noteJson = {
385
- "@context": ["https://www.w3.org/ns/activitystreams", { extra: "https://example.com/ns#extra" }],
386
- type: "Note",
387
- id: "https://example.com/notes/1",
388
- content: "This is text about ap://did:key:z6Mkabc/actor.",
389
- extra: "This extension property should stay cached."
390
- };
391
- deepStrictEqual(await (await Note.fromJsonLd(noteJson, {
392
- documentLoader: mockDocumentLoader,
393
- contextLoader: mockDocumentLoader
394
- })).toJsonLd(), noteJson);
395
- });
396
- test("fromJsonLd() preserves extensions with portable ActivityPub IRIs", async () => {
397
- const jsonLd = await (await Note.fromJsonLd({
398
- "@context": ["https://www.w3.org/ns/activitystreams", { extra: "https://example.com/ns#extra" }],
399
- type: "Note",
400
- id: "ap://did:key:z6Mkabc/objects/1",
401
- extra: "This extension property should stay cached."
402
- }, {
403
- documentLoader: mockDocumentLoader,
404
- contextLoader: mockDocumentLoader
405
- })).toJsonLd();
406
- deepStrictEqual(jsonLd.extra, "This extension property should stay cached.");
407
- deepStrictEqual(jsonLd.id, "ap+ef61://did:key:z6Mkabc/objects/1");
408
- });
409
- test("fromJsonLd() preserves unmapped terms with portable IRIs", async () => {
410
- const jsonLd = await (await Note.fromJsonLd({
411
- "@context": "https://www.w3.org/ns/activitystreams",
412
- type: "Note",
413
- id: "ap://did:key:z6Mkabc/objects/1",
414
- extra: "This unmapped property should stay cached."
415
- }, {
416
- documentLoader: mockDocumentLoader,
417
- contextLoader: mockDocumentLoader
418
- })).toJsonLd();
419
- deepStrictEqual(jsonLd.extra, "This unmapped property should stay cached.");
420
- deepStrictEqual(jsonLd.id, "ap+ef61://did:key:z6Mkabc/objects/1");
421
- });
422
- test("fromJsonLd() preserves expanded arrays with portable IRIs", async () => {
423
- const expanded = [{
424
- "@id": "https://example.com/activities/1",
425
- "@type": ["https://www.w3.org/ns/activitystreams#Create"],
426
- "https://www.w3.org/ns/activitystreams#actor": [{ "@id": "ap://did:key:z6Mkabc/actor" }],
427
- "https://www.w3.org/ns/activitystreams#object": [{ "@id": "https://example.com/objects/1" }]
428
- }, {
429
- "@id": "https://example.com/objects/1",
430
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
431
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "Sibling node should stay cached." }]
432
- }];
433
- const activity = await Activity.fromJsonLd(expanded, {
434
- documentLoader: mockDocumentLoader,
435
- contextLoader: mockDocumentLoader
436
- });
437
- deepStrictEqual(activity.actorId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor"));
438
- deepStrictEqual(await activity.toJsonLd(), [{
439
- "@id": "https://example.com/activities/1",
440
- "@type": ["https://www.w3.org/ns/activitystreams#Create"],
441
- "https://www.w3.org/ns/activitystreams#actor": [{ "@id": "ap+ef61://did:key:z6Mkabc/actor" }],
442
- "https://www.w3.org/ns/activitystreams#object": [{ "@id": "https://example.com/objects/1" }]
443
- }, {
444
- "@id": "https://example.com/objects/1",
445
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
446
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "Sibling node should stay cached." }]
447
- }]);
448
- deepStrictEqual(expanded[0]["https://www.w3.org/ns/activitystreams#actor"], [{ "@id": "ap://did:key:z6Mkabc/actor" }]);
449
- });
450
- test("fromJsonLd() preserves single-node expanded arrays with portable IRIs", async () => {
451
- const expanded = [{
452
- "@id": "ap://did:key:z6Mkabc/objects/1",
453
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
454
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap://did:key:z6Mkabc/actor" }],
455
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "Single expanded node should stay cached as an array." }]
456
- }];
457
- deepStrictEqual(await (await Note.fromJsonLd(expanded, {
458
- documentLoader: mockDocumentLoader,
459
- contextLoader: mockDocumentLoader
460
- })).toJsonLd(), [{
461
- "@id": "ap+ef61://did:key:z6Mkabc/objects/1",
462
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
463
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap+ef61://did:key:z6Mkabc/actor" }],
464
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "Single expanded node should stay cached as an array." }]
465
- }]);
466
- deepStrictEqual(expanded[0]["@id"], "ap://did:key:z6Mkabc/objects/1");
467
- });
468
- test("fromJsonLd() preserves no-context object shape with portable IRIs", async () => {
469
- const expanded = {
470
- "@id": "ap://did:key:z6Mkabc/objects/1",
471
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
472
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap://did:key:z6Mkabc/actor" }],
473
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "No-context object shape should stay cached." }]
474
- };
475
- deepStrictEqual(await (await Note.fromJsonLd(expanded, {
476
- documentLoader: mockDocumentLoader,
477
- contextLoader: mockDocumentLoader
478
- })).toJsonLd(), {
479
- "@id": "ap+ef61://did:key:z6Mkabc/objects/1",
480
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
481
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap+ef61://did:key:z6Mkabc/actor" }],
482
- "https://www.w3.org/ns/activitystreams#content": [{ "@value": "No-context object shape should stay cached." }]
483
- });
484
- deepStrictEqual(expanded["@id"], "ap://did:key:z6Mkabc/objects/1");
485
- });
486
- test("fromJsonLd() preserves expanded subtype cache types", async () => {
487
- const expanded = [{
488
- "@id": "https://example.com/activities/1",
489
- "@type": ["https://www.w3.org/ns/activitystreams#Create"],
490
- "https://www.w3.org/ns/activitystreams#actor": [{ "@id": "https://example.com/actors/alice" }],
491
- "https://www.w3.org/ns/activitystreams#object": [{ "@id": "https://example.com/objects/1" }]
492
- }, {
493
- "@id": "https://example.com/objects/1",
494
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
495
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap://did:key:z6Mkabc/actor" }]
496
- }];
497
- deepStrictEqual(await (await Activity.fromJsonLd(expanded, {
498
- documentLoader: mockDocumentLoader,
499
- contextLoader: mockDocumentLoader
500
- })).toJsonLd(), [{
501
- "@id": "https://example.com/activities/1",
502
- "@type": ["https://www.w3.org/ns/activitystreams#Create"],
503
- "https://www.w3.org/ns/activitystreams#actor": [{ "@id": "https://example.com/actors/alice" }],
504
- "https://www.w3.org/ns/activitystreams#object": [{ "@id": "https://example.com/objects/1" }]
505
- }, {
506
- "@id": "https://example.com/objects/1",
507
- "@type": ["https://www.w3.org/ns/activitystreams#Note"],
508
- "https://www.w3.org/ns/activitystreams#attributedTo": [{ "@id": "ap+ef61://did:key:z6Mkabc/actor" }]
509
- }]);
510
- deepStrictEqual(expanded[0]["@type"], ["https://www.w3.org/ns/activitystreams#Create"]);
511
- });
512
- test("fromJsonLd() preserves compact array contexts with portable IRIs", async () => {
513
- deepStrictEqual(await (await Note.fromJsonLd([{
514
- "@context": "https://www.w3.org/ns/activitystreams",
515
- type: "Note",
516
- id: "ap://did:key:z6Mkabc/objects/1"
517
- }], {
518
- documentLoader: mockDocumentLoader,
519
- contextLoader: mockDocumentLoader
520
- })).toJsonLd(), [{
521
- "@context": "https://www.w3.org/ns/activitystreams",
522
- type: "Note",
523
- id: "ap+ef61://did:key:z6Mkabc/objects/1"
524
- }]);
525
- });
526
- test("fromJsonLd() preserves compact single-item arrays with portable IRIs", async () => {
527
- const createJson = {
528
- "@context": "https://www.w3.org/ns/activitystreams",
529
- type: "Create",
530
- actor: ["ap://did:key:z6Mkabc/actor"],
531
- object: "https://example.com/objects/1"
532
- };
533
- deepStrictEqual(await (await Create.fromJsonLd(createJson, {
534
- documentLoader: mockDocumentLoader,
535
- contextLoader: mockDocumentLoader
536
- })).toJsonLd(), {
537
- "@context": "https://www.w3.org/ns/activitystreams",
538
- type: "Create",
539
- actor: ["ap+ef61://did:key:z6Mkabc/actor"],
540
- object: "https://example.com/objects/1"
541
- });
542
- deepStrictEqual(createJson.actor, ["ap://did:key:z6Mkabc/actor"]);
543
- });
544
- test("fromJsonLd() preserves compact multi-node arrays with portable IRIs", async () => {
545
- deepStrictEqual(await (await Activity.fromJsonLd([{
546
- "@context": "https://www.w3.org/ns/activitystreams",
547
- type: "Create",
548
- id: "https://example.com/activities/1",
549
- actor: "https://example.com/actors/alice",
550
- object: "https://example.com/objects/1"
551
- }, {
552
- "@context": "https://www.w3.org/ns/activitystreams",
553
- type: "Note",
554
- id: "https://example.com/objects/1",
555
- attributedTo: "ap://did:key:z6Mkabc/actor"
556
- }], {
557
- documentLoader: mockDocumentLoader,
558
- contextLoader: mockDocumentLoader
559
- })).toJsonLd(), [{
560
- "@context": "https://www.w3.org/ns/activitystreams",
561
- type: "Create",
562
- id: "https://example.com/activities/1",
563
- actor: "https://example.com/actors/alice",
564
- object: "https://example.com/objects/1"
565
- }, {
566
- "@context": "https://www.w3.org/ns/activitystreams",
567
- type: "Note",
568
- id: "https://example.com/objects/1",
569
- attributedTo: "ap+ef61://did:key:z6Mkabc/actor"
570
- }]);
571
- });
572
- test("fromJsonLd() preserves nested unmapped terms with portable IRIs", async () => {
573
- deepStrictEqual(await (await Note.fromJsonLd({
574
- "@context": "https://www.w3.org/ns/activitystreams",
575
- type: "Note",
576
- id: "ap://did:key:z6Mkabc/objects/1",
577
- attachment: {
578
- type: "Object",
579
- name: "Attachment with an unmapped extension.",
580
- extra: "This nested unmapped property should stay cached."
581
- }
582
- }, {
583
- documentLoader: mockDocumentLoader,
584
- contextLoader: mockDocumentLoader
585
- })).toJsonLd(), {
586
- "@context": "https://www.w3.org/ns/activitystreams",
587
- type: "Note",
588
- id: "ap+ef61://did:key:z6Mkabc/objects/1",
589
- attachment: {
590
- type: "Object",
591
- name: "Attachment with an unmapped extension.",
592
- extra: "This nested unmapped property should stay cached."
593
- }
594
- });
595
- });
596
- test("fromJsonLd() preserves compact array item extension contexts with portable IRIs", async () => {
597
- deepStrictEqual(await (await Activity.fromJsonLd([{
598
- "@context": "https://www.w3.org/ns/activitystreams",
599
- type: "Create",
600
- id: "https://example.com/activities/1",
601
- actor: "https://example.com/actors/alice",
602
- object: "https://example.com/objects/1"
603
- }, {
604
- "@context": ["https://www.w3.org/ns/activitystreams", { extraRef: {
605
- "@id": "https://example.com/ns#extraRef",
606
- "@type": "@id"
607
- } }],
608
- type: "Note",
609
- id: "https://example.com/objects/1",
610
- extraRef: "ap://did:key:z6Mkabc/extra"
611
- }], {
612
- documentLoader: mockDocumentLoader,
613
- contextLoader: mockDocumentLoader
614
- })).toJsonLd(), [{
615
- "@context": "https://www.w3.org/ns/activitystreams",
616
- type: "Create",
617
- id: "https://example.com/activities/1",
618
- actor: "https://example.com/actors/alice",
619
- object: "https://example.com/objects/1"
620
- }, {
621
- "@context": ["https://www.w3.org/ns/activitystreams", { extraRef: {
622
- "@id": "https://example.com/ns#extraRef",
623
- "@type": "@id"
624
- } }],
625
- type: "Note",
626
- id: "https://example.com/objects/1",
627
- extraRef: "ap+ef61://did:key:z6Mkabc/extra"
628
- }]);
629
- });
630
- test("fromJsonLd() formats portable IRIs in JSON-LD containers", async () => {
631
- const jsonLd = await (await Note.fromJsonLd({
632
- "@context": "https://www.w3.org/ns/activitystreams",
633
- type: "Note",
634
- id: "https://example.com/notes/1",
635
- attributedTo: { "@list": ["ap://did:key:z6Mkabc/actor"] },
636
- to: { "@set": ["ap://did:key:z6Mkabc/followers"] }
637
- }, {
638
- documentLoader: mockDocumentLoader,
639
- contextLoader: mockDocumentLoader
640
- })).toJsonLd();
641
- deepStrictEqual(jsonLd.attributedTo, { "@list": ["ap+ef61://did:key:z6Mkabc/actor"] });
642
- deepStrictEqual(jsonLd.to, "ap+ef61://did:key:z6Mkabc/followers");
643
- });
644
- test("fromJsonLd() formats portable IRIs hidden behind JSON-LD aliases", async () => {
645
- const activity = await Activity.fromJsonLd({
646
- "@context": ["https://www.w3.org/ns/activitystreams", {
647
- as: {
648
- "@id": "https://www.w3.org/ns/activitystreams#",
649
- "@prefix": true
650
- },
651
- extra: "https://example.com/ns#extra",
652
- extraRef: {
653
- "@id": "https://example.com/ns#extraRef",
654
- "@type": "@id"
655
- },
656
- actorRef: {
657
- "@id": "as:actor",
658
- "@type": "@id"
659
- },
660
- targetRef: {
661
- "@id": "as:target",
662
- "@type": "@id"
663
- }
664
- }],
665
- type: "Create",
666
- actorRef: "ap://did:key:z6Mkabc/actor",
667
- object: "https://example.com/objects/1",
668
- targetRef: "ap://did:key:z6Mkabc/target",
669
- extra: "This extension property should stay cached.",
670
- extraRef: "ap://did:key:z6Mkabc/extra"
671
- }, {
672
- documentLoader: mockDocumentLoader,
673
- contextLoader: mockDocumentLoader
674
- });
675
- deepStrictEqual(activity.actorId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor"));
676
- deepStrictEqual(activity.targetId, new URL("ap+ef61://did%3Akey%3Az6Mkabc/target"));
677
- const jsonLd = await activity.toJsonLd({ contextLoader: mockDocumentLoader });
678
- deepStrictEqual(jsonLd.actor, "ap+ef61://did:key:z6Mkabc/actor");
679
- deepStrictEqual("actorRef" in jsonLd, false);
680
- deepStrictEqual(jsonLd.target, "ap+ef61://did:key:z6Mkabc/target");
681
- deepStrictEqual("targetRef" in jsonLd, false);
682
- deepStrictEqual(jsonLd.extra, "This extension property should stay cached.");
683
- deepStrictEqual(jsonLd.extraRef, "ap+ef61://did:key:z6Mkabc/extra");
684
- });
685
- test("fromJsonLd() preserves portable IRIs in @id extension terms", async () => {
686
- deepStrictEqual((await (await Note.fromJsonLd({
687
- "@context": ["https://www.w3.org/ns/activitystreams", { extraRef: {
688
- "@id": "https://example.com/ns#extraRef",
689
- "@type": "@id"
690
- } }],
691
- type: "Note",
692
- id: "https://example.com/notes/1",
693
- extraRef: "ap://did:key:z6Mkabc/extra"
694
- }, {
695
- documentLoader: mockDocumentLoader,
696
- contextLoader: mockDocumentLoader
697
- })).toJsonLd({ contextLoader: mockDocumentLoader })).extraRef, "ap+ef61://did:key:z6Mkabc/extra");
698
- });
699
- test("fromJsonLd() ignores malformed portable IRIs in extension cache terms", async () => {
700
- const noteJson = {
701
- "@context": ["https://www.w3.org/ns/activitystreams", { extraRef: {
702
- "@id": "https://example.com/ns#extraRef",
703
- "@type": "@id"
704
- } }],
705
- type: "Note",
706
- id: "https://example.com/notes/1",
707
- extraRef: "ap://example.com/not-portable"
708
- };
709
- deepStrictEqual(await (await Note.fromJsonLd(noteJson, {
710
- documentLoader: mockDocumentLoader,
711
- contextLoader: mockDocumentLoader
712
- })).toJsonLd(), noteJson);
713
- });
714
- test("fromJsonLd() preserves portable IRIs in @id typed terms", async () => {
715
- const jsonLd = await (await Note.fromJsonLd({
716
- "@context": ["https://www.w3.org/ns/activitystreams", {
717
- "@vocab": "https://example.com/ns#",
718
- extraRef: { "@type": "@id" }
719
- }],
720
- type: "Note",
721
- id: "https://example.com/notes/1",
722
- content: "This text mentions ap://did:key:z6Mkabc/text.",
723
- extraRef: "ap://did:key:z6Mkabc/extra"
724
- }, {
725
- documentLoader: mockDocumentLoader,
726
- contextLoader: mockDocumentLoader
727
- })).toJsonLd({ contextLoader: mockDocumentLoader });
728
- deepStrictEqual(jsonLd.content, "This text mentions ap://did:key:z6Mkabc/text.");
729
- deepStrictEqual(jsonLd.extraRef, "ap+ef61://did:key:z6Mkabc/extra");
730
- });
731
- test("fromJsonLd() preserves portable IRIs hidden behind remote contexts", async () => {
732
- const contextUrl = "https://example.com/contexts/portable-iris";
733
- const contextLoader = async (resource, options) => {
734
- if (resource === contextUrl) return {
735
- contextUrl: null,
736
- documentUrl: resource,
737
- document: { "@context": ["https://www.w3.org/ns/activitystreams", {
738
- "@vocab": "https://example.com/ns#",
739
- extra: "https://example.com/ns#extra",
740
- extraRef: { "@type": "@id" }
741
- }] }
742
- };
743
- return await mockDocumentLoader(resource, options);
744
- };
745
- const jsonLd = await (await Note.fromJsonLd({
746
- "@context": contextUrl,
747
- type: "Note",
748
- id: "https://example.com/notes/1",
749
- content: "This text mentions ap://did:key:z6Mkabc/text.",
750
- extra: "This extension property should stay cached.",
751
- extraRef: "ap://did:key:z6Mkabc/extra"
752
- }, {
753
- documentLoader: mockDocumentLoader,
754
- contextLoader
755
- })).toJsonLd({ contextLoader });
756
- deepStrictEqual(jsonLd.content, "This text mentions ap://did:key:z6Mkabc/text.");
757
- deepStrictEqual(jsonLd.extra, "This extension property should stay cached.");
758
- deepStrictEqual(jsonLd.extraRef, "ap+ef61://did:key:z6Mkabc/extra");
759
- });
760
- test("fromJsonLd() formats portable IRIs hidden behind nested remote contexts", async () => {
761
- const rootContextUrl = "https://example.com/contexts/nested-portable-iris";
762
- const nestedContextUrl = "https://example.com/contexts/nested-portable-ref";
763
- const contextLoader = async (resource, options) => {
764
- if (resource === rootContextUrl) return {
765
- contextUrl: null,
766
- documentUrl: resource,
767
- document: { "@context": ["https://www.w3.org/ns/activitystreams", {
768
- "@vocab": "https://example.com/ns#",
769
- extraContainer: "https://example.com/ns#extraContainer"
770
- }] }
771
- };
772
- if (resource === nestedContextUrl) return {
773
- contextUrl: null,
774
- documentUrl: resource,
775
- document: { "@context": {
776
- "@vocab": "https://example.com/ns#",
777
- extra: "https://example.com/ns#extra",
778
- extraRef: { "@type": "@id" }
779
- } }
780
- };
781
- return await mockDocumentLoader(resource, options);
782
- };
783
- deepStrictEqual((await (await Note.fromJsonLd({
784
- "@context": rootContextUrl,
785
- type: "Note",
786
- id: "https://example.com/notes/1",
787
- extraContainer: {
788
- "@context": nestedContextUrl,
789
- content: "This text mentions ap://did:key:z6Mkabc/text.",
790
- extra: "This nested extension object should stay cached.",
791
- extraRef: "ap://did:key:z6Mkabc/extra"
792
- }
793
- }, {
794
- documentLoader: mockDocumentLoader,
795
- contextLoader
796
- })).toJsonLd({ contextLoader })).extraContainer, {
797
- "@context": nestedContextUrl,
798
- content: "This text mentions ap://did:key:z6Mkabc/text.",
799
- extra: "This nested extension object should stay cached.",
800
- extraRef: { id: "ap+ef61://did:key:z6Mkabc/extra" }
801
- });
802
- });
803
- test("fromJsonLd() formats portable IRIs in sibling remote-context objects", async () => {
804
- const rootContextUrl = "https://example.com/contexts/sibling-containers";
805
- const nestedContextUrl = "https://example.com/contexts/sibling-extra-ref";
806
- const contextLoader = async (resource, options) => {
807
- if (resource === rootContextUrl) return {
808
- contextUrl: null,
809
- documentUrl: resource,
810
- document: { "@context": ["https://www.w3.org/ns/activitystreams", {
811
- "@vocab": "https://example.com/ns#",
812
- firstExtraContainer: "https://example.com/ns#firstExtraContainer",
813
- secondExtraContainer: "https://example.com/ns#secondExtraContainer"
814
- }] }
815
- };
816
- if (resource === nestedContextUrl) return {
817
- contextUrl: null,
818
- documentUrl: resource,
819
- document: { "@context": {
820
- "@vocab": "https://example.com/ns#",
821
- extraRef: { "@type": "@id" }
822
- } }
823
- };
824
- return await mockDocumentLoader(resource, options);
825
- };
826
- const jsonLd = await (await Note.fromJsonLd({
827
- "@context": rootContextUrl,
828
- type: "Note",
829
- id: "https://example.com/notes/1",
830
- firstExtraContainer: {
831
- "@context": nestedContextUrl,
832
- content: "No portable IRI here."
833
- },
834
- secondExtraContainer: {
835
- "@context": nestedContextUrl,
836
- extraRef: "ap://did:key:z6Mkabc/second"
837
- }
838
- }, {
839
- documentLoader: mockDocumentLoader,
840
- contextLoader
841
- })).toJsonLd({ contextLoader });
842
- deepStrictEqual(jsonLd.firstExtraContainer, {
843
- "@context": nestedContextUrl,
844
- content: "No portable IRI here."
845
- });
846
- deepStrictEqual(jsonLd.secondExtraContainer, {
847
- "@context": nestedContextUrl,
848
- extraRef: { id: "ap+ef61://did:key:z6Mkabc/second" }
849
- });
850
- });
851
- test("fromJsonLd() batches unmapped portable IRI term checks", async () => {
852
- const contextUrl = "https://example.com/contexts/batched-portable-aliases";
853
- let contextLoads = 0;
854
- const contextLoader = async (resource, options) => {
855
- if (resource === contextUrl) {
856
- contextLoads++;
857
- return {
858
- contextUrl: null,
859
- documentUrl: resource,
860
- document: { "@context": ["https://www.w3.org/ns/activitystreams", {
861
- as: {
862
- "@id": "https://www.w3.org/ns/activitystreams#",
863
- "@prefix": true
864
- },
865
- actorRef0: {
866
- "@id": "as:actor",
867
- "@type": "@id"
868
- },
869
- actorRef1: {
870
- "@id": "as:actor",
871
- "@type": "@id"
872
- },
873
- targetRef0: {
874
- "@id": "as:target",
875
- "@type": "@id"
876
- },
877
- targetRef1: {
878
- "@id": "as:target",
879
- "@type": "@id"
880
- },
881
- objectRef0: {
882
- "@id": "as:object",
883
- "@type": "@id"
884
- },
885
- objectRef1: {
886
- "@id": "as:object",
887
- "@type": "@id"
888
- }
889
- }] }
890
- };
891
- }
892
- return await mockDocumentLoader(resource, options);
893
- };
894
- await (await Activity.fromJsonLd({
895
- "@context": contextUrl,
896
- type: "Create",
897
- actorRef0: "ap://did:key:z6Mkabc/actor0",
898
- actorRef1: "ap://did:key:z6Mkabc/actor1",
899
- targetRef0: "ap://did:key:z6Mkabc/target0",
900
- targetRef1: "ap://did:key:z6Mkabc/target1",
901
- objectRef0: "https://example.com/objects/0",
902
- objectRef1: "https://example.com/objects/1"
903
- }, {
904
- documentLoader: mockDocumentLoader,
905
- contextLoader
906
- })).toJsonLd({ contextLoader });
907
- ok(contextLoads <= 5);
908
- });
909
- test("fromJsonLd() falls back when portable IRI cache merge fails", async () => {
910
- const contextUrl = "https://example.com/contexts/failing-cache-merge";
911
- let contextLoads = 0;
912
- const contextLoader = async (resource, options) => {
913
- if (resource === contextUrl) {
914
- contextLoads++;
915
- if (contextLoads > 1) throw new Error("merge context unavailable");
916
- return {
917
- contextUrl: null,
918
- documentUrl: resource,
919
- document: { "@context": ["https://www.w3.org/ns/activitystreams", {
920
- "@vocab": "https://example.com/ns#",
921
- extraRef: { "@type": "@id" }
922
- }] }
923
- };
924
- }
925
- return await mockDocumentLoader(resource, options);
926
- };
927
- const jsonLd = await (await Note.fromJsonLd({
928
- "@context": contextUrl,
929
- type: "Note",
930
- id: "ap://did:key:z6Mkabc/objects/1",
931
- extraRef: "ap://did:key:z6Mkabc/extra"
932
- }, {
933
- documentLoader: mockDocumentLoader,
934
- contextLoader
935
- })).toJsonLd({ contextLoader: mockDocumentLoader });
936
- deepStrictEqual(jsonLd.type, "Note");
937
- deepStrictEqual(jsonLd.id, "ap+ef61://did:key:z6Mkabc/objects/1");
938
- });
939
- test("fromJsonLd() formats portable IRIs in scalar URL values", async () => {
940
- const note = await Note.fromJsonLd({
941
- "@context": [
942
- "https://www.w3.org/ns/activitystreams",
943
- "https://gotosocial.org/ns",
944
- { quoteUrl: "as:quoteUrl" }
945
- ],
946
- type: "Note",
947
- id: "https://example.com/notes/1",
948
- quoteUrl: "ap://did:key:z6Mkabc/objects/1"
949
- }, {
950
- documentLoader: mockDocumentLoader,
951
- contextLoader: mockDocumentLoader
952
- });
953
- deepStrictEqual(note.quoteUrl, new URL("ap+ef61://did%3Akey%3Az6Mkabc/objects/1"));
954
- deepStrictEqual((await note.toJsonLd({ contextLoader: mockDocumentLoader })).quoteUrl, "ap+ef61://did:key:z6Mkabc/objects/1");
955
- });
956
- test("fromJsonLd() formats portable IRIs in URL value lists", async () => {
957
- const note = await Note.fromJsonLd({
958
- "@context": [
959
- "https://www.w3.org/ns/activitystreams",
960
- "https://gotosocial.org/ns",
961
- { quoteUrl: "as:quoteUrl" }
962
- ],
963
- type: "Note",
964
- id: "https://example.com/notes/1",
965
- quoteUrl: { "@list": [{ "@value": "ap://did:key:z6Mkabc/objects/1" }] }
966
- }, {
967
- documentLoader: mockDocumentLoader,
968
- contextLoader: mockDocumentLoader
969
- });
970
- deepStrictEqual(note.quoteUrl, new URL("ap+ef61://did%3Akey%3Az6Mkabc/objects/1"));
971
- deepStrictEqual((await note.toJsonLd({ contextLoader: mockDocumentLoader })).quoteUrl, { "@list": ["ap+ef61://did:key:z6Mkabc/objects/1"] });
972
- });
973
305
  test({
974
306
  name: "Activity.getObject()",
975
307
  permissions: {
@@ -1025,34 +357,6 @@ test({
1025
357
  });
1026
358
  }
1027
359
  });
1028
- test("Activity.getObject() fetches canonical portable IRIs", async () => {
1029
- const fetchedUrls = [];
1030
- const documentLoader = async (url) => {
1031
- fetchedUrls.push(url);
1032
- return {
1033
- contextUrl: null,
1034
- documentUrl: url,
1035
- document: {
1036
- "@context": "https://www.w3.org/ns/activitystreams",
1037
- id: url,
1038
- type: "Note",
1039
- content: "Fetched portable object"
1040
- }
1041
- };
1042
- };
1043
- assertInstanceOf(await (await Activity.fromJsonLd({
1044
- "@context": "https://www.w3.org/ns/activitystreams",
1045
- type: "Create",
1046
- object: "ap://did:key:z6Mkabc/objects/1"
1047
- }, {
1048
- documentLoader,
1049
- contextLoader: mockDocumentLoader
1050
- })).getObject({
1051
- documentLoader,
1052
- contextLoader: mockDocumentLoader
1053
- }), Note);
1054
- deepStrictEqual(fetchedUrls, ["ap+ef61://did:key:z6Mkabc/objects/1"]);
1055
- });
1056
360
  test({
1057
361
  name: "Activity.getObjects()",
1058
362
  permissions: {
@@ -1161,7 +465,6 @@ test("Person.toJsonLd()", async () => {
1161
465
  "https://www.w3.org/ns/did/v1",
1162
466
  "https://w3id.org/security/multikey/v1",
1163
467
  "https://gotosocial.org/ns",
1164
- "https://w3id.org/fep/7aa9",
1165
468
  {
1166
469
  PropertyValue: "schema:PropertyValue",
1167
470
  alsoKnownAs: {
@@ -1177,10 +480,6 @@ test("Person.toJsonLd()", async () => {
1177
480
  "@id": "toot:featured",
1178
481
  "@type": "@id"
1179
482
  },
1180
- featuredCollections: {
1181
- "@id": "https://w3id.org/fep/7aa9#featuredCollections",
1182
- "@type": "@id"
1183
- },
1184
483
  featuredTags: {
1185
484
  "@id": "toot:featuredTags",
1186
485
  "@type": "@id"
@@ -1627,187 +926,6 @@ test("InteractionPolicy.canQuote", async () => {
1627
926
  contextLoader: mockDocumentLoader
1628
927
  })).toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1629
928
  });
1630
- test("InteractionPolicy.canFeature", async () => {
1631
- const person = new Person({
1632
- id: new URL("https://example.com/users/alice"),
1633
- featuredCollections: new URL("https://example.com/users/alice/featured_collections"),
1634
- interactionPolicy: new InteractionPolicy({ canFeature: new InteractionRule({ automaticApproval: new URL("https://www.w3.org/ns/activitystreams#Public") }) })
1635
- });
1636
- const expected = {
1637
- "@context": [
1638
- "https://www.w3.org/ns/activitystreams",
1639
- "https://w3id.org/security/v1",
1640
- "https://w3id.org/security/data-integrity/v1",
1641
- "https://www.w3.org/ns/did/v1",
1642
- "https://w3id.org/security/multikey/v1",
1643
- "https://gotosocial.org/ns",
1644
- "https://w3id.org/fep/7aa9",
1645
- {
1646
- Emoji: "toot:Emoji",
1647
- PropertyValue: "schema:PropertyValue",
1648
- _misskey_followedMessage: "misskey:_misskey_followedMessage",
1649
- alsoKnownAs: {
1650
- "@id": "as:alsoKnownAs",
1651
- "@type": "@id"
1652
- },
1653
- discoverable: "toot:discoverable",
1654
- featured: {
1655
- "@id": "toot:featured",
1656
- "@type": "@id"
1657
- },
1658
- featuredCollections: {
1659
- "@id": "https://w3id.org/fep/7aa9#featuredCollections",
1660
- "@type": "@id"
1661
- },
1662
- featuredTags: {
1663
- "@id": "toot:featuredTags",
1664
- "@type": "@id"
1665
- },
1666
- indexable: "toot:indexable",
1667
- isCat: "misskey:isCat",
1668
- manuallyApprovesFollowers: "as:manuallyApprovesFollowers",
1669
- memorial: "toot:memorial",
1670
- misskey: "https://misskey-hub.net/ns#",
1671
- movedTo: {
1672
- "@id": "as:movedTo",
1673
- "@type": "@id"
1674
- },
1675
- schema: "http://schema.org#",
1676
- suspended: "toot:suspended",
1677
- toot: "http://joinmastodon.org/ns#",
1678
- value: "schema:value"
1679
- }
1680
- ],
1681
- type: "Person",
1682
- id: "https://example.com/users/alice",
1683
- featuredCollections: "https://example.com/users/alice/featured_collections",
1684
- interactionPolicy: { canFeature: { automaticApproval: "as:Public" } }
1685
- };
1686
- deepStrictEqual(await person.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1687
- const loaded = await Person.fromJsonLd(expected, {
1688
- documentLoader: mockDocumentLoader,
1689
- contextLoader: mockDocumentLoader
1690
- });
1691
- deepStrictEqual(loaded.featuredCollectionsId, new URL("https://example.com/users/alice/featured_collections"));
1692
- assertInstanceOf(loaded.interactionPolicy, InteractionPolicy);
1693
- assertInstanceOf(loaded.interactionPolicy.canFeature, InteractionRule);
1694
- deepStrictEqual(loaded.interactionPolicy.canFeature.automaticApproval, new URL("https://www.w3.org/ns/activitystreams#Public"));
1695
- deepStrictEqual(await loaded.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1696
- deepStrictEqual((await Person.fromJsonLd({
1697
- "@context": [
1698
- "https://www.w3.org/ns/activitystreams",
1699
- "https://gotosocial.org/ns",
1700
- "https://w3id.org/fep/7aa9",
1701
- { featuredCollections: {
1702
- "@id": "https://w3id.org/fep/7aa9#featuredCollections",
1703
- "@type": "@id"
1704
- } }
1705
- ],
1706
- type: "Person",
1707
- id: "https://example.com/users/alice",
1708
- featuredCollections: "https://example.com/users/alice/featured_collections"
1709
- }, {
1710
- documentLoader: mockDocumentLoader,
1711
- contextLoader: mockDocumentLoader
1712
- })).featuredCollectionsId, new URL("https://example.com/users/alice/featured_collections"));
1713
- });
1714
- test("FeaturedCollection.toJsonLd()", async () => {
1715
- const collection = new FeaturedCollection({
1716
- id: new URL("https://example.com/users/alice/featured/1"),
1717
- name: "Cute cats",
1718
- attribution: new URL("https://example.com/users/alice"),
1719
- topic: new Hashtag({ name: "#cats" }),
1720
- discoverable: false,
1721
- totalItems: 1
1722
- });
1723
- const expected = {
1724
- "@context": FEATURED_COLLECTION_CONTEXT,
1725
- type: "FeaturedCollection",
1726
- id: "https://example.com/users/alice/featured/1",
1727
- attributedTo: "https://example.com/users/alice",
1728
- name: "Cute cats",
1729
- totalItems: 1,
1730
- topic: {
1731
- type: "Hashtag",
1732
- name: "#cats"
1733
- },
1734
- discoverable: false
1735
- };
1736
- deepStrictEqual(await collection.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1737
- const loaded = await FeaturedCollection.fromJsonLd(expected, {
1738
- documentLoader: mockDocumentLoader,
1739
- contextLoader: mockDocumentLoader
1740
- });
1741
- assertInstanceOf(loaded, FeaturedCollection);
1742
- deepStrictEqual(loaded.name, "Cute cats");
1743
- deepStrictEqual(loaded.attributionId, new URL("https://example.com/users/alice"));
1744
- assertInstanceOf(loaded.topic, Hashtag);
1745
- deepStrictEqual(loaded.topic.name, "#cats");
1746
- deepStrictEqual(loaded.discoverable, false);
1747
- deepStrictEqual(loaded.totalItems, 1);
1748
- deepStrictEqual(await loaded.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1749
- });
1750
- test("FeaturedItem.toJsonLd()", async () => {
1751
- const item = new FeaturedItem({
1752
- id: new URL("https://example.com/users/alice/featured/1/items/1"),
1753
- featuredObject: new URL("https://example.com/users/bob"),
1754
- featureAuthorization: new URL("https://example.com/users/bob/stamps/1")
1755
- });
1756
- const expected = {
1757
- "@context": FEATURE_CONTEXT,
1758
- type: "FeaturedItem",
1759
- id: "https://example.com/users/alice/featured/1/items/1",
1760
- featuredObject: "https://example.com/users/bob",
1761
- featureAuthorization: "https://example.com/users/bob/stamps/1"
1762
- };
1763
- deepStrictEqual(await item.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1764
- const loaded = await FeaturedItem.fromJsonLd(expected, {
1765
- documentLoader: mockDocumentLoader,
1766
- contextLoader: mockDocumentLoader
1767
- });
1768
- assertInstanceOf(loaded, FeaturedItem);
1769
- deepStrictEqual(loaded.featuredObjectId, new URL("https://example.com/users/bob"));
1770
- deepStrictEqual(loaded.featureAuthorizationId, new URL("https://example.com/users/bob/stamps/1"));
1771
- });
1772
- test("FeatureAuthorization.fromJsonLd()", async () => {
1773
- const jsonLd = {
1774
- "@context": FEATURE_CONTEXT,
1775
- type: "FeatureAuthorization",
1776
- id: "https://example.com/users/bob/stamps/1",
1777
- interactingObject: "https://example.com/users/alice/featured/1",
1778
- interactionTarget: "https://example.com/users/bob"
1779
- };
1780
- const authorization = await FeatureAuthorization.fromJsonLd(jsonLd, {
1781
- documentLoader: mockDocumentLoader,
1782
- contextLoader: mockDocumentLoader
1783
- });
1784
- assertInstanceOf(authorization, FeatureAuthorization);
1785
- deepStrictEqual(authorization.interactingObjectId, new URL("https://example.com/users/alice/featured/1"));
1786
- deepStrictEqual(authorization.interactionTargetId, new URL("https://example.com/users/bob"));
1787
- deepStrictEqual(await authorization.toJsonLd({ contextLoader: mockDocumentLoader }), jsonLd);
1788
- });
1789
- test("FeatureRequest.toJsonLd()", async () => {
1790
- const request = new FeatureRequest({
1791
- id: new URL("https://example.com/users/alice/featured/1/requests/1"),
1792
- object: new URL("https://example.com/users/bob"),
1793
- instrument: new URL("https://example.com/users/alice/featured/1")
1794
- });
1795
- const expected = {
1796
- "@context": ["https://w3id.org/identity/v1", ...FEATURE_CONTEXT],
1797
- type: "FeatureRequest",
1798
- id: "https://example.com/users/alice/featured/1/requests/1",
1799
- object: "https://example.com/users/bob",
1800
- instrument: "https://example.com/users/alice/featured/1"
1801
- };
1802
- deepStrictEqual(await request.toJsonLd({ contextLoader: mockDocumentLoader }), expected);
1803
- const loaded = await FeatureRequest.fromJsonLd(expected, {
1804
- documentLoader: mockDocumentLoader,
1805
- contextLoader: mockDocumentLoader
1806
- });
1807
- assertInstanceOf(loaded, FeatureRequest);
1808
- deepStrictEqual(loaded.objectId, new URL("https://example.com/users/bob"));
1809
- deepStrictEqual(loaded.instrumentId, new URL("https://example.com/users/alice/featured/1"));
1810
- });
1811
929
  test("QuoteAuthorization.fromJsonLd()", async () => {
1812
930
  const jsonLd = {
1813
931
  "@context": [
@@ -2512,26 +1630,6 @@ test("FEP-fe34: crossOrigin trust behavior", async () => {
2512
1630
  deepStrictEqual(result?.id, new URL("https://malicious.com/fake-note"));
2513
1631
  deepStrictEqual(result?.content, "This is a spoofed note");
2514
1632
  });
2515
- test("FEP-fe34: id-less owners honor crossOrigin trust", async () => {
2516
- const result = await (await Create.fromJsonLd({
2517
- "@context": "https://www.w3.org/ns/activitystreams",
2518
- "@type": "Create",
2519
- "actor": "https://example.com/actor",
2520
- "object": {
2521
- "@type": "Note",
2522
- "@id": "https://different-origin.com/note",
2523
- "content": "Embedded note"
2524
- }
2525
- })).getObject({
2526
- crossOrigin: "trust",
2527
- documentLoader: async (url) => {
2528
- throw new Error(`Unexpected fetch: ${url}`);
2529
- }
2530
- });
2531
- assertInstanceOf(result, Note);
2532
- deepStrictEqual(result.id, new URL("https://different-origin.com/note"));
2533
- deepStrictEqual(result.content, "Embedded note");
2534
- });
2535
1633
  test("FEP-fe34: Same origin objects are trusted", async () => {
2536
1634
  const sameOriginDocumentLoader = async (url) => {
2537
1635
  if (url === "https://example.com/note") return {
@@ -2627,35 +1725,6 @@ test("FEP-fe34: Constructor vs JSON-LD parsing trust difference", async () => {
2627
1725
  };
2628
1726
  deepStrictEqual((await jsonLdCreate.getObject({ documentLoader }))?.content, "Fetched from origin");
2629
1727
  });
2630
- test("FEP-fe34: Portable DID authorities are cross-origin boundaries", async () => {
2631
- const create = await Create.fromJsonLd({
2632
- "@context": "https://www.w3.org/ns/activitystreams",
2633
- "@type": "Create",
2634
- "@id": "ap://did:key:z6MkOwner/create",
2635
- "actor": "ap://did:key:z6MkOwner/actor",
2636
- "object": {
2637
- "@type": "Note",
2638
- "@id": "ap://did:key:z6MkOther/note",
2639
- "content": "Embedded portable note"
2640
- }
2641
- });
2642
- const documentLoader = async (url) => {
2643
- if (url === "ap+ef61://did:key:z6MkOther/note") return {
2644
- documentUrl: url,
2645
- contextUrl: null,
2646
- document: {
2647
- "@context": "https://www.w3.org/ns/activitystreams",
2648
- "@type": "Note",
2649
- "@id": "ap://did:key:z6MkOther/note",
2650
- "content": "Fetched portable note"
2651
- }
2652
- };
2653
- throw new Error("Document not found");
2654
- };
2655
- const result = await create.getObject({ documentLoader });
2656
- assertInstanceOf(result, Note);
2657
- deepStrictEqual(result.content, "Fetched portable note");
2658
- });
2659
1728
  test("FEP-fe34: Array properties respect cross-origin policy", async () => {
2660
1729
  const crossOriginDocumentLoader = async (url) => {
2661
1730
  if (url === "https://different-origin.com/note1") return {
@@ -2729,60 +1798,6 @@ test("FEP-fe34: Array properties with crossOrigin trust option", async () => {
2729
1798
  deepStrictEqual(items[0].content, "Fake note 1");
2730
1799
  deepStrictEqual(items[1].content, "Legitimate note 2");
2731
1800
  });
2732
- test("FEP-fe34: id-less arrays honor crossOrigin trust", async () => {
2733
- const collection = await Collection.fromJsonLd({
2734
- "@context": "https://www.w3.org/ns/activitystreams",
2735
- "@type": "Collection",
2736
- "items": [{
2737
- "@type": "Note",
2738
- "@id": "https://different-origin.com/note1",
2739
- "content": "Embedded note 1"
2740
- }, {
2741
- "@type": "Note",
2742
- "@id": "https://different-origin.com/note2",
2743
- "content": "Embedded note 2"
2744
- }]
2745
- });
2746
- const items = [];
2747
- for await (const item of collection.getItems({
2748
- crossOrigin: "trust",
2749
- documentLoader: async (url) => {
2750
- throw new Error(`Unexpected fetch: ${url}`);
2751
- }
2752
- })) items.push(item);
2753
- deepStrictEqual(items.length, 2);
2754
- assertInstanceOf(items[0], Note);
2755
- assertInstanceOf(items[1], Note);
2756
- deepStrictEqual(items[0].content, "Embedded note 1");
2757
- deepStrictEqual(items[1].content, "Embedded note 2");
2758
- });
2759
- test("FEP-fe34: Array properties track trust per item", async () => {
2760
- const collection = new Collection({
2761
- id: new URL("https://example.com/collection"),
2762
- items: [new Note({
2763
- id: new URL("https://malicious.com/fake-note1"),
2764
- content: "Trusted constructor note 1"
2765
- }), new URL("https://different-origin.com/note2")]
2766
- });
2767
- const documentLoader = async (url) => {
2768
- if (url === "https://different-origin.com/note2") return {
2769
- documentUrl: url,
2770
- contextUrl: null,
2771
- document: {
2772
- "@context": "https://www.w3.org/ns/activitystreams",
2773
- "@type": "Note",
2774
- "@id": "https://malicious.com/fake-note2",
2775
- "content": "Untrusted fetched note 2"
2776
- }
2777
- };
2778
- throw new Error("Document not found");
2779
- };
2780
- const items = [];
2781
- for await (const item of collection.getItems({ documentLoader })) items.push(item);
2782
- deepStrictEqual(items.length, 1);
2783
- assertInstanceOf(items[0], Note);
2784
- deepStrictEqual(items[0].content, "Trusted constructor note 1");
2785
- });
2786
1801
  test("FEP-fe34: Embedded objects in arrays from JSON-LD respect cross-origin policy", async () => {
2787
1802
  const collectionDocumentLoader = async (url) => {
2788
1803
  if (url === "https://example.com/collection") return {