shares collection MUST be either an OrderedCollection or a Collection

Description

This test case tests that an actor's shares collection is an expected kind of collection

Table of Contents

Identifiers

Use these identifiers to refer to this Test.

URI

urn:uuid:b03a5245-1072-426d-91b3-a3d412d45ae8

slug

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

shares-collection-must-be-a-collection

Input

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

input.object

the object whose `shares` property will be tested

required
true
range
https://www.w3.org/ns/activitystreams#Actor

input.object as json
{
  "help": "the object whose `shares` property will be tested",
  "required": true,
  "rangeIncludes": [
    "https://www.w3.org/ns/activitystreams#Actor"
  ]
}

Input as JSON
{
  "object": {
    "help": "the object whose `shares` property will be tested",
    "required": true,
    "rangeIncludes": [
      "https://www.w3.org/ns/activitystreams#Actor"
    ]
  }
}

Requirement Mapping

This Test has been derived from these specified requirements.

  • urn:uuid:937ae4e2-dd33-40c7-be1d-3ecac7f9fad5

    content
    The shares collection MUST be either an OrderedCollection or a Collection
    origin
    {
      "source": "https://www.w3.org/TR/activitypub/",
      "section": {
        "id": "https://www.w3.org/TR/activitypub/#shares",
        "branch": [
          5,
          8
        ]
      },
      "selector": {
        "type": "TextQuoteSelector",
        "prefix": "Every object MAY have a shares collection. This is a list of all Announce activities with this object as the object property, added as a side effect.\n",
        "exact": "The shares collection MUST be either an OrderedCollection or a Collection\n",
        "suffix": "and MAY be filtered on privileges of an authenticated user or as appropriate when no authentication is given. \n"
      }
    }
    JSON
    {
      "id": "urn:uuid:937ae4e2-dd33-40c7-be1d-3ecac7f9fad5",
      "type": "Behavior",
      "uuid": "937ae4e2-dd33-40c7-be1d-3ecac7f9fad5",
      "content": "The shares collection MUST be either an OrderedCollection or a Collection\n",
      "tag": [
        {
          "name": "ActivityPubServer",
          "id": "https://socialweb.coop/tag/ActivityPubServer"
        }
      ],
      "origin": {
        "source": "https://www.w3.org/TR/activitypub/",
        "section": {
          "id": "https://www.w3.org/TR/activitypub/#shares",
          "branch": [
            5,
            8
          ]
        },
        "selector": {
          "type": "TextQuoteSelector",
          "prefix": "Every object MAY have a shares collection. This is a list of all Announce activities with this object as the object property, added as a side effect.\n",
          "exact": "The shares collection MUST be either an OrderedCollection or a Collection\n",
          "suffix": "and MAY be filtered on privileges of an authenticated user or as appropriate when no authentication is given. \n"
        }
      },
      "@context": [
        "https://www.w3.org/ns/activitystreams",
        "https://socialweb.coop/ns/testing/context.json"
      ]
    }

Part of

This test is part of the following Test Suites:

JSON

Test Case as JSON
{
  "description": "This test case tests that an actor's shares collection is an expected kind of collection",
  "input": {
    "object": {
      "help": "the object whose `shares` property will be tested",
      "required": true,
      "rangeIncludes": [
        "https://www.w3.org/ns/activitystreams#Actor"
      ]
    }
  },
  "markdown": "---\ntype:\n- TestCase\nstatus: draft\nname: shares collection MUST be either an OrderedCollection or a Collection\nslug: shares-collection-must-be-a-collection\ndescription: |\n  This rule checks that the shares collection of an ActivityPub Object, if present, is an OrderedCollection or a Collection.\nuuid: b03a5245-1072-426d-91b3-a3d412d45ae8\nattributedTo:\n- https://bengo.is\n\"@context\":\n- TestCase:\n    \"@id\": http://www.w3.org/ns/earl#:TestCase\n\nrespec:\n  config:\n    editors:\n    - name: bengo\n      url: \"https://bengo.is\"\n      w3cid: 49026\n---\n\n# shares collection MUST be either an OrderedCollection or a Collection\n\n## Background\n\n[ActivityPub](https://www.w3.org/TR/activitypub/) [ยง 5.8 Shares Collection](https://www.w3.org/TR/activitypub/#shares):\n> Every object MAY have a shares collection.…\n> The shares collection MUST be either an OrderedCollection or a Collection\n\n## About this Test\n\nThis is a Test describing a rule to determine whether an ActivityPub object has a `shares` property whose value conforms to a the [requirement](https://socialweb.coop/activitypub/behaviors/937ae4e2-dd33-40c7-be1d-3ecac7f9fad5/) that \"The shares collection MUST be either an OrderedCollection or a Collection\".\n\n### Identifier\n\nThe identifier of this test is `urn:uuid:b03a5245-1072-426d-91b3-a3d412d45ae8`.\n\n## Test Subject\n\nThe subject of this test is data claiming to conform to the specification of an [ActivityPub Object](https://www.w3.org/TR/activitypub/#obj).\n\nThis test is *not* inherently applicable to an ActivityPub Server. An ActivityPub Server serves 1 or more ActivityPub Objects.\n\nThis test is *not* inherently applicable to a URL that resolves to an ActivityPub Object. The URL is not the same as the Object. The URL may resolve to different Objects in different contexts. Dereference the URL to test the referent with this test.\n\n## Inputs\n\nThis test requires the following [inputs](https://www.w3.org/TR/act-rules-format/#input):\n\n1. `object` - the object whose `shares` property will be tested\n    * type: binary\n    * constraints\n        * will be interepreted as JSON\n\n## Applicability\n\nThis test applies to the the `shares` property on the input `object`.\n\nThis test does not apply to objects with more than one shares collection. If the input `object` has a `shares` property whose value is an array length >= 2, the test outcome is `inapplicable`.\n\nThis test does not apply to objects for which a `shares` collection cannot be found.\nIf input `object` is not parseable as JSON to a JSON object, the test outcome is `inapplicable`.\nIf input `object` is a JSON object, but it does not contain a property named `shares`, the test outcome is `inapplicable`.\n\n### Test Targets\n\n1. `shares` - the shares collection derived from the input `object` and its `shares` property\n    * because this is the value of a property from the input `object` that must be a JSON object, the value of this `shares` target will also be JSON\n    * how to derive `shares` from inputs\n        1. let `inputs.object` be the JSON object parsed from input `object`\n        2. let `propertyValue` be\n            * if `inputs.object.shares` is a JSON string, `propertyValue` is that string\n            * if `inputs.object.shares` is a JSON object, `propertyValue` is that object\n            * if `inputs.object.shares` is an Array of length 1, `propertyValue` is the item in that array\n            * if `inputs.object.shares` is an Array of length greater than 1, the test outcome is `inapplicable` (covered in 'Applicability' above)\n        3. let `value` be\n          *if `outboxValue` is a json string, `value` is the result of interpreting that string as an ActivityPub Object Identifier, fetching the corresponding ActivityPub Object (e.g. `GET https://...`), and parsing the resulting response body as `application/json`.\n          * otherwise `value` is `outboxValue`\n        4. test target `shares` is equal to `value`\n\n## Expectations\n\n1. `shares` is a JSON object\n2. `shares` has a property named `type`\n3. the values of the `shares` target's `type` property must indicate that the value is either an OrderedCollection or a Collection as determined by:\n    * if the value of the `shares` target's `type` property is a string, it MUST be equal to either `\"OrderedCollection\"` or `\"Collection\"`\n    * if the value of the `shares` target's `type` property is an Array, it MUST contain an entry for at least one of `\"OrderedCollection\"` or `\"Collection\"`\n\n## Assumptions\n\n### Interpreting \"MUST be either an OrderedCollection or a Collection\"\n\nThis test chose to interpret 'MUST be… an' to include 'indicate its type as'. The rationale is:\n\n* it's easy to check and implement.\n* I can't think of a better alternative\n* I haven't received any objections\n\n## Test Cases\n\n### simple passed case\n\ninputs\n\n* `object`\n\n    ```json\n    {\n      shares: [{\n        type: [\"Collection\"]\n      }]\n    }\n    ```\n\ntest targets\n\n* `shares`\n\n    ```json\n    {\n      \"type\": [\"Collection\"]\n    }\n    ```\n\n    * outcome: `passed`\n\n### object.shares is a number\n\ninputs\n\n* `object`\n\n  ```json\n  {\n    shares: 1\n  }\n  ```\n\ntest targets\n\n* `shares`\n\n  ```json\n  1\n  ```\n\n    * outcome: `failed`\n        * rationale: shares does not seem to \"be either an OrderedCollection or a Collection\"\n\n### object is number\n\ninputs\n\n* `object`\n\n  ```json\n  1\n  ```\n\nresult\n\n* outcome: `inapplicable`\n\n## Glossary\n\n### `outcome`\n\nAn outcome is a conclusion that comes from evaluating a test on a test subject. An outcome can be one of the three following types:\n\n* `inapplicable`: No part of the test subject matches the applicability\n* `passed`: A test target meets all expectations\n* `failed`: A test target does not meet all expectations\n\n## Requirements Mapping\n\n* [ActivityPub Requirement 937ae4e2-dd33-40c7-be1d-3ecac7f9fad5](https://socialweb.coop/activitypub/behaviors/937ae4e2-dd33-40c7-be1d-3ecac7f9fad5) - \"The shares collection MUST be either an OrderedCollection or a Collection\"\n    * Required for Conformance to [ActivityPub][activitypub]\n    * Outcome Mapping\n        * when test target `shares` has outcome `passed`, requirement is satisfied\n        * when test target `shares` has outcome `failed`, requirement is not satisfied\n        * when test target `shares` has outcome `inapplicable`, further testing is needed to determine requirement satisfaction\n\n## Change Log\n\n* 2023-11-28T22:01:58.195Z - first draft\n* 2023-12-29T23:06:48.611Z - format test cases section so each test case has a heading\n\n## Issues\n\n* [ ] ff7a: expand applicability to cover objects with `shares` property whose value is an array of length >= 2\n    * or perhaps just make another more ambitious test case\n\n[activitypub]: https://www.w3.org/TR/activitypub/\n",
  "name": "shares collection MUST be either an OrderedCollection or a Collection",
  "slug": "shares-collection-must-be-a-collection",
  "uuid": "b03a5245-1072-426d-91b3-a3d412d45ae8",
  "inapplicableCases": [
    {
      "name": "object is number",
      "input": {
        "object": "1"
      },
      "result": {
        "outcome": "inapplicable"
      }
    },
    {
      "name": "object has no shares property",
      "input": {
        "object": "{}"
      },
      "result": {
        "outcome": "inapplicable"
      }
    },
    {
      "name": "object has shares property value with array of length 2",
      "input": {
        "object": "{\"shares\":[1,2]}"
      },
      "result": {
        "outcome": "inapplicable"
      }
    }
  ],
  "passedCases": [
    {
      "name": "simple object w/ shares",
      "input": {
        "object": "{\"shares\":{\"type\":\"Collection\"}}"
      },
      "result": {
        "outcome": "passed"
      }
    },
    {
      "name": "object has shares property value with array of length 1",
      "input": {
        "object": "{\"shares\":[{\"type\":[\"Collection\"]}]}"
      },
      "result": {
        "outcome": "passed"
      }
    }
  ],
  "failedCases": [
    {
      "name": "shares is a number",
      "input": {
        "object": "{\"shares\":1}"
      },
      "result": {
        "outcome": "failed"
      }
    },
    {
      "name": "shares has non-collection type",
      "input": {
        "object": "{\"shares\":{\"type\":[\"Person\"]}}"
      },
      "result": {
        "outcome": "failed"
      }
    },
    {
      "name": "shares null type",
      "input": {
        "object": "{\"shares\":{\"type\":null}}"
      },
      "result": {
        "outcome": "failed"
      }
    }
  ],
  "isPartOf": [
    "https://socialweb.coop/activitypub/test-cases/"
  ],
  "requirementReference": [
    {
      "id": "urn:uuid:937ae4e2-dd33-40c7-be1d-3ecac7f9fad5",
      "url": "https://socialweb.coop/activitypub/behaviors/937ae4e2-dd33-40c7-be1d-3ecac7f9fad5/"
    }
  ]
}