Create then Update modifies an Object as checked by getting the Object after the Update

Description

A test rule that sends to an ActivityPub Outbox a Create Activity creating an Object, then sends an Update Activity for that object, then sends an http get to the object URI and expects the object to be modified by the Update.

Table of Contents

Identifiers

Use these identifiers to refer to this Test.

URI

urn:uuid:08efdc1e-195e-4e36-a2b3-e33205bb737b

slug

This slug is memorable, but it is not guaranteed to be globally unique like a URI.

create-then-update-modifies-object-checked-by-get

Input

This describes the input that each test run will use to select test targets.

input.outbox

the url to the Outbox handling an Activity POST request

required
true
type
xsd:anyUri
range
https://www.w3.org/ns/activitystreams#outbox

input.outbox as json
{
  "help": "the url to the Outbox handling an Activity POST request",
  "required": true,
  "type": "xsd:anyUri",
  "rangeIncludes": [
    "https://www.w3.org/ns/activitystreams#outbox"
  ]
}

input.authorization

HTTP Authorization header value to include in outbox POST request

required
false
type
xsd:string, https://activitypub-testing.socialweb.coop/ns/HiddenInTestResults
range
https://www.rfc-editor.org/rfc/rfc9110#field.authorization.value

input.authorization as json
{
  "help": "HTTP Authorization header value to include in outbox POST request",
  "required": false,
  "type": [
    "xsd:string",
    "https://activitypub-testing.socialweb.coop/ns/HiddenInTestResults"
  ],
  "rangeIncludes": [
    "https://www.rfc-editor.org/rfc/rfc9110#field.authorization.value"
  ]
}

Input as JSON
{
  "outbox": {
    "help": "the url to the Outbox handling an Activity POST request",
    "required": true,
    "type": "xsd:anyUri",
    "rangeIncludes": [
      "https://www.w3.org/ns/activitystreams#outbox"
    ]
  },
  "authorization": {
    "help": "HTTP Authorization header value to include in outbox POST request",
    "required": false,
    "type": [
      "xsd:string",
      "https://activitypub-testing.socialweb.coop/ns/HiddenInTestResults"
    ],
    "rangeIncludes": [
      "https://www.rfc-editor.org/rfc/rfc9110#field.authorization.value"
    ]
  }
}

Applicability ?

This test applies only when it is possible to
send a Create activity submission to the outbox,
follow the response Location header to the result of submission,
inspect the resulting activity to see the id provisioned for its object,
send an Update activity to update that object,
fetch the object,
and determine whether the update occurred.

To derive test targets, we'll need to do the above and make serveral requests:
* POST outbox with a Create to create an object
* fetch the result of that to determine the object id
* POST outbox with an Update to update the object with that id
* fetch the object by id

How to derive test targets from input:
* input.outbox MUST be a URI
* let create be `{"type": "Create": "object": {"type":"Note","content":"v0"}}`
* let createObjectResponse be the http response from using an ActivityPub Client to send create to input.outbox including, if available, input.authorization as the Authorization header
* let createObjectLocation be the value of createObjectResponse's http response header named 'location'. If it is a relative URI, resolve it to an absolute uri using a base uri of input.outbox.
* let fetchedCreate be the result of using an activitypub client to fetch the ActivityPub object at createObjectLocatioh. If available, send input.authorization as the Authorization header.
* let createdObjectId be fetchedCreate.object.id. This should be a URI assigned by the outbox server.
* let update be `{"type": "Update", "object": { "id": createdObjectId, "content": "v1" }}`
* use an ActivityPub Client to send update to input.outbox
* the test runner may wait some time to allow the outbox server to process the update
* let objectV1Response be the http response from using an ActivityPub Client to fetch the ActivityPub Object at createdObjectId
* let target.objectV1 be the response body of objectV1Response

Expectations ?

* target.objectV1 MUST be a JSON object
* target.objectV1.content MUST be `"v1"`

Requirement Mapping

This Test has been derived from these specified requirements.

  • urn:uuid:c1cd98fe-ae9c-48a7-9b43-cdd8eb008bc8

    content
    the object MUST be modified to reflect the new structure as defined in the update activity
    origin
    {
      "source": "https://www.w3.org/TR/activitypub/",
      "section": {
        "id": "https://www.w3.org/TR/activitypub/#update-activity-outbox",
        "name": "Update Activity",
        "branch": [
          6,
          3
        ]
      },
      "selector": {
        "type": "TextQuoteSelector",
        "prefix": "The Update activity is used when updating an already existing object.\n",
        "exact": "The side effect of this is that the object MUST be modified to reflect the new structure as defined in the update activity, assuming the actor has permission to update this object.\n",
        "suffix": "6.3.1 Partial Updates\n"
      }
    }
    JSON
    {
      "id": "urn:uuid:c1cd98fe-ae9c-48a7-9b43-cdd8eb008bc8",
      "uuid": "c1cd98fe-ae9c-48a7-9b43-cdd8eb008bc8",
      "type": "Behavior",
      "content": "the object MUST be modified to reflect the new structure as defined in the update activity\n",
      "tag": [
        {
          "name": "ActivityPubServer",
          "id": "https://socialweb.coop/tag/ActivityPubServer"
        }
      ],
      "context": [
        "https://www.w3.org/TR/activitypub/",
        {
          "name": "6. Client to Server Interactions",
          "id": "https://www.w3.org/TR/activitypub/#client-to-server-interactions"
        },
        {
          "name": "6.3 Update Activity",
          "id": "https://www.w3.org/TR/activitypub/#update-activity-outbox"
        }
      ],
      "origin": {
        "source": "https://www.w3.org/TR/activitypub/",
        "section": {
          "id": "https://www.w3.org/TR/activitypub/#update-activity-outbox",
          "name": "Update Activity",
          "branch": [
            6,
            3
          ]
        },
        "selector": {
          "type": "TextQuoteSelector",
          "prefix": "The Update activity is used when updating an already existing object.\n",
          "exact": "The side effect of this is that the object MUST be modified to reflect the new structure as defined in the update activity, assuming the actor has permission to update this object.\n",
          "suffix": "6.3.1 Partial Updates\n"
        }
      },
      "@context": [
        "https://www.w3.org/ns/activitystreams",
        "https://socialweb.coop/ns/testing/context.json"
      ]
    }

JSON

Test Case as JSON
{
  "name": "Create then Update modifies an Object as checked by getting the Object after the Update",
  "description": "A test rule that sends to an ActivityPub Outbox a Create Activity creating an Object, then sends an Update Activity for that object, then sends an http get to the object URI and expects the object to be modified by the Update.",
  "slug": "create-then-update-modifies-object-checked-by-get",
  "uuid": "08efdc1e-195e-4e36-a2b3-e33205bb737b",
  "input": {
    "outbox": {
      "help": "the url to the Outbox handling an Activity POST request",
      "required": true,
      "type": "xsd:anyUri",
      "rangeIncludes": [
        "https://www.w3.org/ns/activitystreams#outbox"
      ]
    },
    "authorization": {
      "help": "HTTP Authorization header value to include in outbox POST request",
      "required": false,
      "type": [
        "xsd:string",
        "https://activitypub-testing.socialweb.coop/ns/HiddenInTestResults"
      ],
      "rangeIncludes": [
        "https://www.rfc-editor.org/rfc/rfc9110#field.authorization.value"
      ]
    }
  },
  "applicability": "This test applies only when it is possible to\nsend a Create activity submission to the outbox,\nfollow the response Location header to the result of submission,\ninspect the resulting activity to see the id provisioned for its object,\nsend an Update activity to update that object,\nfetch the object,\nand determine whether the update occurred.\n\nTo derive test targets, we'll need to do the above and make serveral requests:\n* POST outbox with a Create to create an object\n* fetch the result of that to determine the object id\n* POST outbox with an Update to update the object with that id\n* fetch the object by id\n\nHow to derive test targets from input:\n* input.outbox MUST be a URI\n* let create be `{\"type\": \"Create\": \"object\": {\"type\":\"Note\",\"content\":\"v0\"}}`\n* let createObjectResponse be the http response from using an ActivityPub Client to send create to input.outbox including, if available, input.authorization as the Authorization header\n* let createObjectLocation be the value of createObjectResponse's http response header named 'location'. If it is a relative URI, resolve it to an absolute uri using a base uri of input.outbox.\n* let fetchedCreate be the result of using an activitypub client to fetch the ActivityPub object at createObjectLocatioh. If available, send input.authorization as the Authorization header.\n* let createdObjectId be fetchedCreate.object.id. This should be a URI assigned by the outbox server.\n* let update be `{\"type\": \"Update\", \"object\": { \"id\": createdObjectId, \"content\": \"v1\" }}`\n* use an ActivityPub Client to send update to input.outbox\n* the test runner may wait some time to allow the outbox server to process the update\n* let objectV1Response be the http response from using an ActivityPub Client to fetch the ActivityPub Object at createdObjectId\n* let target.objectV1 be the response body of objectV1Response",
  "expectations": "* target.objectV1 MUST be a JSON object\n* target.objectV1.content MUST be `\"v1\"`",
  "requirementReference": [
    {
      "id": "urn:uuid:c1cd98fe-ae9c-48a7-9b43-cdd8eb008bc8",
      "url": "https://activitypub-testing-website.socialweb.coop/c1cd98fe-ae9c-48a7-9b43-cdd8eb008bc8"
    }
  ]
}