# activitypub-testing + FEP-521a

&horbar;[bengo][]

## Contents

* [Context](#context)
* [Running the FEP-521a Test on an Actor input as a JSON string](#running-the-fep-521a-test-on-an-actor-input-as-a-json-string)
* [Running the FEP-521a Test on an Actor fetched via curl](#running-the-fep-521a-test-on-an-actor-fetched-via-curl)
    * [testing actor `https://mitra.social/users/weekinfediverse`](#testing-actor-httpsmitrasocialusersweekinfediverse)
    * [testing actor `https://socialweb.coop`](#testing-actor-httpssocialwebcoop)
* [testing fedify.dev with activitypub-testing-fedify](#testing-fedifydev-with-activitypub-testing-fedify)

## Context

`activitypub-testing` can run tests for Fediverse Enhancement Proposals. Let's use FEP-521a as an example:

[FEP-521a: Representing actor's public keys](https://codeberg.org/fediverse/fep/src/branch/main/fep/521a/fep-521a.md) is a **FEP Specification** by silverpill @<silverpill@mitra.social> specifying how to represent public keys associated with ActivityPub actors.

@bumblefudge.com later added a **FEP Test Specification** for [a FEP-521a Test](https://codeberg.org/fediverse/fep/src/branch/main/fep/521a/fep-521a-test-case.md). This is a human-readable specification of a test procedure that verifies that a test subject implements the normative requirements specified by FEP-521a.

@bengo.is later created a **FEP Test Implementation** for the FEP-521a Test in JavaScript and published [activitypub-testing-fep-521a](https://codeberg.org/socialweb.coop/activitypub-testing-fep-521a/). The repo also makes the test's JavaScript file [available over HTTP](https://codeberg.org/socialweb.coop/activitypub-testing-fep-521a/raw/branch/main/fep/521a/actor-objects-must-express-signing-key-as-assertionMethod-multikey.js), and this URL is used later to instruct `activitypub-testing run test` to run a test from a remote URL.

`activitypub-testing` can create **Test Run**s for the FEP-521a Test Implementation.

## Running the FEP-521a Test on an Actor input as a JSON string

use `activitypub-testing run test` with the `--url` flag set to the URL to the custom test module. `activitypub-testing` will fetch the URL, load the test, and then apply the test to the input built from the other CLI flags.

```shell
activitypub-testing run test \
--url=https://codeberg.org/socialweb.coop/activitypub-testing-fep-521a/raw/branch/main/fep/521a/actor-objects-must-express-signing-key-as-assertionMethod-multikey.js \
--input.actor='{"type":"Person","assertionMethod":[{"type":"Multikey","id": "https://example.com/#ed25519-key","controller": "https://example.com/","publicKeyMultibase": "6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2"}]}'
```

<details>
  <summary>show output</summary>
  <pre>
  {
    "type": [
      "Assertion"
    ],
    "result": {
      "outcome": "failed",
      "pointer": {
        "results": [
          {
            "target": {
              "actor": {
                "type": "Person",
                "assertionMethod": [
                  {
                    "type": "Multikey",
                    "id": "https://example.com/#ed25519-key",
                    "controller": "https://example.com/",
                    "publicKeyMultibase": "6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2"
                  }
                ]
              },
              "assertionMethod": {
                "type": "Multikey",
                "id": "https://example.com/#ed25519-key",
                "controller": "https://example.com/",
                "publicKeyMultibase": "6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2"
              }
            },
            "result": {
              "outcome": "failed",
              "info": "assertionMethod is not a valid fep-521a multikey",
              "pointer": {
                "error": {
                  "message": "assertionMethod.publicKeyMultibase MUST be a string startwith with 'z' (i.e. multibase-base58btc)",
                  "cause": {
                    "assertionMethod": {
                      "type": "Multikey",
                      "id": "https://example.com/#ed25519-key",
                      "controller": "https://example.com/",
                      "publicKeyMultibase": "6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2"
                    }
                  }
                }
              }
            }
          }
        ]
      }
    },
    "test": {
      "slug": "fep-521a-actor-objects-must-express-signing-key-as-assertionmethod-multikey",
      "description": "This rule checks whether a given Actor Object has a Multikey object in top-level assertionMethod property of the shape specified in FEP-521a.",
      "name": "Actor Objects must express signing key as assertionMethod Multikey",
      "id": "urn:uuid:36f73f6e-8c14-4606-864d-32b9a74abc87",
      "requirementReference": []
    },
    "input": {
      "actor": "{\"type\":\"Person\",\"assertionMethod\":[{\"type\":\"Multikey\",\"id\": \"https://example.com/#ed25519-key\",\"controller\": \"https://example.com/\",\"publicKeyMultibase\": \"6MkrJVnaZkeFzdQyMZu1cgjg7k1pZZ6pvBQ7XJPt4swbTQ2\"}]}"
    },
    "@context": [
      "https://socialweb.coop/ns/testing/context.json",
      "https://www.w3.org/ns/activitystreams"
    ]
  }
  </pre>
</details>

## Running the FEP-521a Test on an Actor fetched via curl

_thanks to `@silverpill` from mitra.social for volunteering a test vector!_

Use `activitypub-testing run test` with the `--url` flag set to the URL to the custom test module as before. `activitypub-testing` will fetch the URL, load the test, and then apply the test to the input built from the other CLI flags.

Implementations that will return full Actor objects to unauthenticated callers can simply call `curl` inside a `$()` evaluation, provided the right HTTP content-type headers are passed for Content Evaluation. The same syntax could be used to test an implementation requiring the caller to be authenticated by authenticating out of band to get an Authorization header to also pass manually.

### testing actor `https://mitra.social/users/weekinfediverse`

```shell
testFep521aActorUrl() {
    activitypub-testing run test \
      --url=https://codeberg.org/socialweb.coop/activitypub-testing-fep-521a/raw/branch/main/fep/521a/actor-objects-must-express-signing-key-as-assertionMethod-multikey.js \
      --input.actor="$(curl -H 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' "$1")"
}

testFep521aActorUrl https://mitra.social/users/weekinfediverse
```

<details>
  <summary>show output</summary>
  <pre>
  {
    "type": [
      "Assertion"
    ],
    "result": {
      "outcome": "passed",
      "pointer": {
        "results": [
          {
            "target": {
              "actor": {
                "@context": [
                  "https://www.w3.org/ns/activitystreams",
                  "https://www.w3.org/ns/did/v1",
                  "https://w3id.org/security/v1",
                  "https://w3id.org/security/data-integrity/v1",
                  "https://w3id.org/security/multikey/v1",
                  {
                    "PropertyValue": "schema:PropertyValue",
                    "subscribers": "mitra:subscribers",
                    "proofValue": "sec:proofValue",
                    "schema": "http://schema.org/",
                    "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
                    "value": "schema:value",
                    "mitra": "http://jsonld.mitra.social#",
                    "MitraJcsEip191Signature2022": "mitra:MitraJcsEip191Signature2022",
                    "VerifiableIdentityStatement": "mitra:VerifiableIdentityStatement",
                    "toot": "http://joinmastodon.org/ns#",
                    "featured": "toot:featured",
                    "gateways": "mitra:gateways",
                    "proofPurpose": "sec:proofPurpose"
                  }
                ],
                "id": "https://mitra.social/users/weekinfediverse",
                "type": "Person",
                "name": "Week in Fediverse",
                "preferredUsername": "weekinfediverse",
                "inbox": "https://mitra.social/users/weekinfediverse/inbox",
                "outbox": "https://mitra.social/users/weekinfediverse/outbox",
                "followers": "https://mitra.social/users/weekinfediverse/followers",
                "following": "https://mitra.social/users/weekinfediverse/following",
                "subscribers": "https://mitra.social/users/weekinfediverse/subscribers",
                "featured": "https://mitra.social/users/weekinfediverse/collections/featured",
                "assertionMethod": [
                  {
                    "id": "https://mitra.social/users/weekinfediverse#main-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n"
                  },
                  {
                    "id": "https://mitra.social/users/weekinfediverse#ed25519-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda"
                  }
                ],
                "authentication": [
                  {
                    "id": "https://mitra.social/users/weekinfediverse#main-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n"
                  },
                  {
                    "id": "https://mitra.social/users/weekinfediverse#ed25519-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda"
                  }
                ],
                "publicKey": {
                  "id": "https://mitra.social/users/weekinfediverse#main-key",
                  "owner": "https://mitra.social/users/weekinfediverse",
                  "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwF/l9uMehWwoLOh4W/18\nP8Avhv3pxw5nlZx/5gmOiXQ1A6rvdwQXY6Y24f+C4zUQyYTkfZ5QD8zh4Z52dd2V\n8bbjTNcOmdmjZAhOEGGBcqd2ckONnrOBVVESaGbTTTffjFc1/rclQokacv20WTOQ\nyZ3NSeu/WiSHTJlkEFvs1pP6YuTLRy0qpYfsMWcMruf1mtihwPj8kqtz4WqY9Jce\nG0/vhTR2XfDHc2JYEg6sPLe+5wuq6qL5n5UNL3UR0I90jfm6qKnXE0mnfkXT5rhv\nm51XF3/kdzkGYopOmvi4PyL8xz/yMyltGEkIkckfv8yuSHS8THhwZVE2NKp+suZg\nQwIDAQAB\n-----END PUBLIC KEY-----\n"
                },
                "icon": {
                  "type": "Image",
                  "url": "https://mitra.social/media/94b1ca41dd450eaf9bd5c8edf0723281c06eb9f03bc107e31c9e2a07a86f8c2d.png",
                  "mediaType": null
                },
                "summary": "Weekly Fediverse news.<br>Only Free and Open Source software.<br>Atom feed: <a href=\"https://mitra.social/feeds/users/weekinfediverse\" rel=\"noopener\">https://mitra.social/feeds/users/weekinfediverse</a>",
                "manuallyApprovesFollowers": false,
                "url": "https://mitra.social/users/weekinfediverse"
              },
              "assertionMethod": {
                "id": "https://mitra.social/users/weekinfediverse#main-key",
                "type": "Multikey",
                "controller": "https://mitra.social/users/weekinfediverse",
                "publicKeyMultibase": "z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n"
              }
            },
            "result": {
              "outcome": "passed"
            }
          },
          {
            "target": {
              "actor": {
                "@context": [
                  "https://www.w3.org/ns/activitystreams",
                  "https://www.w3.org/ns/did/v1",
                  "https://w3id.org/security/v1",
                  "https://w3id.org/security/data-integrity/v1",
                  "https://w3id.org/security/multikey/v1",
                  {
                    "PropertyValue": "schema:PropertyValue",
                    "subscribers": "mitra:subscribers",
                    "proofValue": "sec:proofValue",
                    "schema": "http://schema.org/",
                    "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
                    "value": "schema:value",
                    "mitra": "http://jsonld.mitra.social#",
                    "MitraJcsEip191Signature2022": "mitra:MitraJcsEip191Signature2022",
                    "VerifiableIdentityStatement": "mitra:VerifiableIdentityStatement",
                    "toot": "http://joinmastodon.org/ns#",
                    "featured": "toot:featured",
                    "gateways": "mitra:gateways",
                    "proofPurpose": "sec:proofPurpose"
                  }
                ],
                "id": "https://mitra.social/users/weekinfediverse",
                "type": "Person",
                "name": "Week in Fediverse",
                "preferredUsername": "weekinfediverse",
                "inbox": "https://mitra.social/users/weekinfediverse/inbox",
                "outbox": "https://mitra.social/users/weekinfediverse/outbox",
                "followers": "https://mitra.social/users/weekinfediverse/followers",
                "following": "https://mitra.social/users/weekinfediverse/following",
                "subscribers": "https://mitra.social/users/weekinfediverse/subscribers",
                "featured": "https://mitra.social/users/weekinfediverse/collections/featured",
                "assertionMethod": [
                  {
                    "id": "https://mitra.social/users/weekinfediverse#main-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n"
                  },
                  {
                    "id": "https://mitra.social/users/weekinfediverse#ed25519-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda"
                  }
                ],
                "authentication": [
                  {
                    "id": "https://mitra.social/users/weekinfediverse#main-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n"
                  },
                  {
                    "id": "https://mitra.social/users/weekinfediverse#ed25519-key",
                    "type": "Multikey",
                    "controller": "https://mitra.social/users/weekinfediverse",
                    "publicKeyMultibase": "z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda"
                  }
                ],
                "publicKey": {
                  "id": "https://mitra.social/users/weekinfediverse#main-key",
                  "owner": "https://mitra.social/users/weekinfediverse",
                  "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwF/l9uMehWwoLOh4W/18\nP8Avhv3pxw5nlZx/5gmOiXQ1A6rvdwQXY6Y24f+C4zUQyYTkfZ5QD8zh4Z52dd2V\n8bbjTNcOmdmjZAhOEGGBcqd2ckONnrOBVVESaGbTTTffjFc1/rclQokacv20WTOQ\nyZ3NSeu/WiSHTJlkEFvs1pP6YuTLRy0qpYfsMWcMruf1mtihwPj8kqtz4WqY9Jce\nG0/vhTR2XfDHc2JYEg6sPLe+5wuq6qL5n5UNL3UR0I90jfm6qKnXE0mnfkXT5rhv\nm51XF3/kdzkGYopOmvi4PyL8xz/yMyltGEkIkckfv8yuSHS8THhwZVE2NKp+suZg\nQwIDAQAB\n-----END PUBLIC KEY-----\n"
                },
                "icon": {
                  "type": "Image",
                  "url": "https://mitra.social/media/94b1ca41dd450eaf9bd5c8edf0723281c06eb9f03bc107e31c9e2a07a86f8c2d.png",
                  "mediaType": null
                },
                "summary": "Weekly Fediverse news.<br>Only Free and Open Source software.<br>Atom feed: <a href=\"https://mitra.social/feeds/users/weekinfediverse\" rel=\"noopener\">https://mitra.social/feeds/users/weekinfediverse</a>",
                "manuallyApprovesFollowers": false,
                "url": "https://mitra.social/users/weekinfediverse"
              },
              "assertionMethod": {
                "id": "https://mitra.social/users/weekinfediverse#ed25519-key",
                "type": "Multikey",
                "controller": "https://mitra.social/users/weekinfediverse",
                "publicKeyMultibase": "z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda"
              }
            },
            "result": {
              "outcome": "passed"
            }
          }
        ]
      }
    },
    "test": {
      "slug": "fep-521a-actor-objects-must-express-signing-key-as-assertionmethod-multikey",
      "description": "This rule checks whether a given Actor Object has a Multikey object in top-level assertionMethod property of the shape specified in FEP-521a.",
      "name": "Actor Objects must express signing key as assertionMethod Multikey",
      "id": "urn:uuid:36f73f6e-8c14-4606-864d-32b9a74abc87",
      "requirementReference": []
    },
    "input": {
      "actor": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",{\"PropertyValue\":\"schema:PropertyValue\",\"subscribers\":\"mitra:subscribers\",\"proofValue\":\"sec:proofValue\",\"schema\":\"http://schema.org/\",\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"value\":\"schema:value\",\"mitra\":\"http://jsonld.mitra.social#\",\"MitraJcsEip191Signature2022\":\"mitra:MitraJcsEip191Signature2022\",\"VerifiableIdentityStatement\":\"mitra:VerifiableIdentityStatement\",\"toot\":\"http://joinmastodon.org/ns#\",\"featured\":\"toot:featured\",\"gateways\":\"mitra:gateways\",\"proofPurpose\":\"sec:proofPurpose\"}],\"id\":\"https://mitra.social/users/weekinfediverse\",\"type\":\"Person\",\"name\":\"Week in Fediverse\",\"preferredUsername\":\"weekinfediverse\",\"inbox\":\"https://mitra.social/users/weekinfediverse/inbox\",\"outbox\":\"https://mitra.social/users/weekinfediverse/outbox\",\"followers\":\"https://mitra.social/users/weekinfediverse/followers\",\"following\":\"https://mitra.social/users/weekinfediverse/following\",\"subscribers\":\"https://mitra.social/users/weekinfediverse/subscribers\",\"featured\":\"https://mitra.social/users/weekinfediverse/collections/featured\",\"assertionMethod\":[{\"id\":\"https://mitra.social/users/weekinfediverse#main-key\",\"type\":\"Multikey\",\"controller\":\"https://mitra.social/users/weekinfediverse\",\"publicKeyMultibase\":\"z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n\"},{\"id\":\"https://mitra.social/users/weekinfediverse#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://mitra.social/users/weekinfediverse\",\"publicKeyMultibase\":\"z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda\"}],\"authentication\":[{\"id\":\"https://mitra.social/users/weekinfediverse#main-key\",\"type\":\"Multikey\",\"controller\":\"https://mitra.social/users/weekinfediverse\",\"publicKeyMultibase\":\"z4MXj1wBzi9jUstyPh1QLs4sk3bFKPeBeQKXvaqSvg8XbGFSHWanMEsntGBEuCWxHSf6vvEXmA5DvYVhcrsr3RwXVrbejdjaZGkHaPPq17Fxd75Fr2xcaLKavboCKA1f1v58ce5pm17o4Ldhob16eQzFhwjo9YA7DraTeSBqw6C1ZHRVFNikUYhUHcR92ivuJzJ79gcrWbKa8GgpyA4uXQJrkhm9FVHJ7yfEEspnC7dBiqMyf8GuRHXeef29wKP5y2v2ySYQdReoEgmvx65ARw2FkYo4Ga1foRPNwmn4kT6TtGz6RPjJbaMAiaKL74yQVCUZVvw2KaVhVTaZN4Ch8mvgpPSycRfV4XFUmgispPBwVZr8EgJ5n\"},{\"id\":\"https://mitra.social/users/weekinfediverse#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://mitra.social/users/weekinfediverse\",\"publicKeyMultibase\":\"z6MkuXdkTDa1iAZraZCRT9N5BpXKZxvBYpR4T7EG4tTxYuda\"}],\"publicKey\":{\"id\":\"https://mitra.social/users/weekinfediverse#main-key\",\"owner\":\"https://mitra.social/users/weekinfediverse\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwF/l9uMehWwoLOh4W/18\\nP8Avhv3pxw5nlZx/5gmOiXQ1A6rvdwQXY6Y24f+C4zUQyYTkfZ5QD8zh4Z52dd2V\\n8bbjTNcOmdmjZAhOEGGBcqd2ckONnrOBVVESaGbTTTffjFc1/rclQokacv20WTOQ\\nyZ3NSeu/WiSHTJlkEFvs1pP6YuTLRy0qpYfsMWcMruf1mtihwPj8kqtz4WqY9Jce\\nG0/vhTR2XfDHc2JYEg6sPLe+5wuq6qL5n5UNL3UR0I90jfm6qKnXE0mnfkXT5rhv\\nm51XF3/kdzkGYopOmvi4PyL8xz/yMyltGEkIkckfv8yuSHS8THhwZVE2NKp+suZg\\nQwIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"icon\":{\"type\":\"Image\",\"url\":\"https://mitra.social/media/94b1ca41dd450eaf9bd5c8edf0723281c06eb9f03bc107e31c9e2a07a86f8c2d.png\",\"mediaType\":null},\"summary\":\"Weekly Fediverse news.<br>Only Free and Open Source software.<br>Atom feed: <a href=\\\"https://mitra.social/feeds/users/weekinfediverse\\\" rel=\\\"noopener\\\">https://mitra.social/feeds/users/weekinfediverse</a>\",\"manuallyApprovesFollowers\":false,\"url\":\"https://mitra.social/users/weekinfediverse\"}"
    },
    "@context": [
      "https://socialweb.coop/ns/testing/context.json",
      "https://www.w3.org/ns/activitystreams"
    ]
  }
  </pre>
</details>

[bengo]: https://bengo.is


### testing actor `https://socialweb.coop`

```shell
testFep521aActorUrl() {
    activitypub-testing run test \
      --url=https://codeberg.org/socialweb.coop/activitypub-testing-fep-521a/raw/branch/main/fep/521a/actor-objects-must-express-signing-key-as-assertionMethod-multikey.js \
      --input.actor="$(curl -H 'Accept: application/ld+json; profile="https://www.w3.org/ns/activitystreams"' "$1")"
}

testFep521aActorUrl https://socialweb.coop
```

<details>
  <summary>show output</summary>
  <pre>
  {
    "type": [
      "Assertion"
    ],
    "result": {
      "outcome": "passed",
      "pointer": {
        "results": [
          {
            "target": {
              "actor": {
                "type": [
                  "Organization"
                ],
                "inbox": "https://socialweb.coop/inbox",
                "outbox": "https://socialweb.coop/outbox",
                "followers": {
                  "type": "OrderedCollection",
                  "orderedItems": []
                },
                "following": {
                  "type": "OrderedCollection",
                  "orderedItems": []
                },
                "liked": {
                  "type": "OrderedCollection",
                  "orderedItems": []
                },
                "likes": {
                  "type": "OrderedCollection",
                  "orderedItems": []
                },
                "shares": {
                  "type": "OrderedCollection",
                  "orderedItems": []
                },
                "assertionMethod": [
                  {
                    "@context": "https://w3id.org/security/multikey/v1",
                    "id": "did:key:zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu",
                    "type": "Multikey",
                    "controller": "https://socialweb.coop/",
                    "publicKeyMultibase": "zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu"
                  }
                ],
                "id": "https://socialweb.coop/",
                "@context": [
                  "https://www.w3.org/ns/activitystreams"
                ]
              },
              "assertionMethod": {
                "@context": "https://w3id.org/security/multikey/v1",
                "id": "did:key:zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu",
                "type": "Multikey",
                "controller": "https://socialweb.coop/",
                "publicKeyMultibase": "zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu"
              }
            },
            "result": {
              "outcome": "passed"
            }
          }
        ]
      }
    },
    "test": {
      "slug": "fep-521a-actor-objects-must-express-signing-key-as-assertionmethod-multikey",
      "description": "This rule checks whether a given Actor Object has a Multikey object in top-level assertionMethod property of the shape specified in FEP-521a.",
      "name": "Actor Objects must express signing key as assertionMethod Multikey",
      "id": "urn:uuid:36f73f6e-8c14-4606-864d-32b9a74abc87",
      "requirementReference": []
    },
    "input": {
      "actor": "{\n  \"type\": [\n    \"Organization\"\n  ],\n  \"inbox\": \"https://socialweb.coop/inbox\",\n  \"outbox\": \"https://socialweb.coop/outbox\",\n  \"followers\": {\n    \"type\": \"OrderedCollection\",\n    \"orderedItems\": []\n  },\n  \"following\": {\n    \"type\": \"OrderedCollection\",\n    \"orderedItems\": []\n  },\n  \"liked\": {\n    \"type\": \"OrderedCollection\",\n    \"orderedItems\": []\n  },\n  \"likes\": {\n    \"type\": \"OrderedCollection\",\n    \"orderedItems\": []\n  },\n  \"shares\": {\n    \"type\": \"OrderedCollection\",\n    \"orderedItems\": []\n  },\n  \"assertionMethod\": [\n    {\n      \"@context\": \"https://w3id.org/security/multikey/v1\",\n      \"id\": \"did:key:zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu\",\n      \"type\": \"Multikey\",\n      \"controller\": \"https://socialweb.coop/\",\n      \"publicKeyMultibase\": \"zUC74rmg3DP89jrZLWz4zCCNpdFNfSN7917S3nLcw7PVYy5utecjtDF2Tyhu6AETVSnH5ts5z3mSiwi8c4iRJeebTThQFd8cmav9tD7M6dXotab2M6dmCHZX8hxJSNSejUGcntu\"\n    }\n  ],\n  \"id\": \"https://socialweb.coop/\",\n  \"@context\": [\n    \"https://www.w3.org/ns/activitystreams\"\n  ]\n}"
    },
    "@context": [
      "https://socialweb.coop/ns/testing/context.json",
      "https://www.w3.org/ns/activitystreams"
    ]
  }
  </pre>
</details>

## testing fedify.dev with activitypub-testing-fedify

[activitypub-testing-fedify](https://github.com/gobengo/activitypub-testing-fedify/) is a repository that tests an ActivityPub server powered by [fedify.dev](https://fedify.dev/) using activitypub-testing and activitypub-testing-fep-521a.

The [CI job runs `bin/activitypub-testing`](https://github.com/gobengo/activitypub-testing-fedify/blob/cdc83d99b0958bb5e5f71745a3088104d2838fec/.github/workflows/activitypub-testing.yaml#L21), [which invokes](https://github.com/gobengo/activitypub-testing-fedify/commit/cdc83d99b0958bb5e5f71745a3088104d2838fec#diff-ef1a58bc763ca4be059e7680bc2b0d3da8afcd32f05368a0042125ee7a09ef4dR40) `activitypub-testing run test --url=<url-to-fep-521a-test>`.

GitHub Actions job logs [show that the test ran and the result outcome is `passed`](https://github.com/gobengo/activitypub-testing-fedify/actions/runs/9766712199/job/26960293304#step:5:74).
