tests whether an ActivityPub Object has a likes collection with an appropriate Collection type
Use these identifiers to refer to this Test.
urn:uuid:200b9bc8-aae3-46f2-a6ab-5366042c0f6e
This slug is memorable, but it is not guaranteed to be globally unique like a URI.
likes-collection-must-be-a-collection
This describes the input that each test run will use to select test targets.
object with a likes property
{ "help": "object with a likes property", "required": true, "rangeIncludes": [ "https://www.w3.org/ns/activitystreams#Actor" ] }
{ "object": { "help": "object with a likes property", "required": true, "rangeIncludes": [ "https://www.w3.org/ns/activitystreams#Actor" ] } }
This Test has been derived from these specified requirements.
{ "source": "https://www.w3.org/TR/activitypub/", "section": { "id": "https://www.w3.org/TR/activitypub/#likes", "branch": [ 5, 7 ] }, "selector": { "type": "TextQuoteSelector", "prefix": "Every object MAY have a likes collection. This is a list of all Like activities with this object as the object property, added as a side effect.\n", "exact": "The likes 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" } }
{ "id": "urn:uuid:f965e989-4084-4f9d-9119-6a7ea13bcb64", "type": "Behavior", "uuid": "f965e989-4084-4f9d-9119-6a7ea13bcb64", "content": "The likes 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/#likes", "branch": [ 5, 7 ] }, "selector": { "type": "TextQuoteSelector", "prefix": "Every object MAY have a likes collection. This is a list of all Like activities with this object as the object property, added as a side effect.\n", "exact": "The likes 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" ] }
This test is part of the following Test Suites:
{ "input": { "object": { "help": "object with a likes property", "required": true, "rangeIncludes": [ "https://www.w3.org/ns/activitystreams#Actor" ] } }, "markdown": "---\n\ntype:\n- TestCase\ntags:\n- tests-activitypub-object\nuuid:\n- 200b9bc8-aae3-46f2-a6ab-5366042c0f6e\n\nrespec:\n config:\n editors:\n - name: bengo\n url: \"https://bengo.is\"\n w3cid: 49026\n---\n\n# An ActivityPub Object `likes` Collection Must be a Collection\n\n## Background\n\n[ActivityPub][activitypub] says\n> Every object MAY have a likes collection.\n> …\n> The likes collection MUST be either an OrderedCollection or a Collection\n\n## About This Test\n\nThis is a Test Case describing a rule to determine whether an ActivityPub Object is in partial conformance with the following behaviors required by [ActivityPub][activitypub].\n\n* [requirement f965e989-4084-4f9d-9119-6a7ea13bcb64](https://socialweb.coop/activitypub/behaviors/f965e989-4084-4f9d-9119-6a7ea13bcb64/) - The likes collection MUST be either an OrderedCollection or a Collection\n\n### Identifier\n\nThe identifier of this test is `urn:uuid:200b9bc8-aae3-46f2-a6ab-5366042c0f6e`.\n\n## Test Subject\n\nThe subject of this test is an ActivityPub Object.\n\n## Input\n\nThis test requires the following [inputs](act-rules-input) indicating parts of the test subject:\n\n### `input.object`\n\nthe object whose `likes` property will be tested\n\n* type: binary\n* constraints\n * should be JSON\n\n## Applicability\n\nThis test applies to each of the likes collections derived from the values of the property on `object` named `likes`.\n\n### Prerequisites\n\n* `object` is a JSON object\n* `object` JSON object has a property named `likes`\n\n### Test Targets\n\nHow to Derive Test Targets from Input\n\n* let `targets` be a set\n* let `likesValues` be the result of\n * if `object.likes` is an Array, return it\n * else return an Array whose only item is the value of `object.likes`\n* for each item in `likesValues`\n * if item is a string\n * let itemFetched be the result of interpreting the string as an ActivityPub Object Identifier and fetching the corresponding ActivityPub Object.\n * add itemFetched to `targets`\n * else add item to `targets`\n* return `targets`\n\n## Expectations\n\nFor every target `target`\n\n* `target` is a JSON object\n* `target` has a property named `type`\n* the value of the `target`'s `type` property must be one of\n * an array containing the string \"Collection\"\n * an array containing the string \"OrderedCollection\"\n * the string \"Collection\"\n * the string \"OrderedCollection\"\n\n## Test Cases\n\nWhat follows are some specific cases of applything this test rule.\n\n### Passed Example 1\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": {\n \"type\": \"Collection\"\n }\n }\n ```\n\ntest targets\n\n* ```json\n {\n \"type\": \"Collection\"\n }\n ```\n\n * outcome: `passed`\n\n### Passed Example 2\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": {\n \"type\": \"OrderedCollection\"\n }\n }\n ```\n\ntest targets\n\n* ```json\n {\n \"type\": \"OrderedCollection\"\n }\n ```\n\n * outcome: `passed`\n\n### Passed Example 3\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": {\n \"type\": [\"FancyCollection\", \"OrderedCollection\"]\n }\n }\n ```\n\ntest targets\n\n* ```json\n {\n \"likes\": {\n \"type\": [\"FancyCollection\", \"OrderedCollection\"]\n }\n }\n ```\n\n * outcome: `passed`\n * rationale: `\"FancyCollection\"` is not well-defined here, but this object still passes the test because at least one of the `type` property values is `OrderedCollection` and thus satisfies the requirement as interpreted.\n\n### Failed Example 1 - Likes is a number\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": 1\n }\n ```\n\ntest targets\n\n* ```json\n 1\n ```\n\n * outcome: `failed`\n\n### Failed Example 2 - Likes is an empty object\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": {}\n }\n ```\n\ntest targets\n\n* ```json\n {}\n ```\n\n * outcome: `failed`\n\n### Failed Example 3 - Likes object type is array including only `\"Link\"`\n\ninputs\n\n* `object`:\n\n ```json\n {\n \"likes\": {\n \"type\": [\"Link\"]\n }\n }\n ```\n\ntest targets\n\n* ```json\n {\n \"type\": [\"Link\"]\n }\n ```\n\n * outcome: `failed`\n\n### Inapplicable Example 1\n\ninputs\n\n* `object`:\n\n ```json\n 1\n ```\n\nresult\n\n* outcome: `inapplicable`\n\n### Inapplicable Example 2 - object has no likes property\n\ninputs\n\n* `object`:\n\n ```json\n { \"foo\": \"bar\" }\n ```\n\nresult\n\n* outcome: `inapplicable`\n\n### Inapplicable Example 3 - object is html\n\ninputs\n\n* `object`:\n\n ```html\n <!doctype html>hi\n ```\n\nresult\n\n* outcome: `inapplicable`\n\n## Glossary [<sup>?</sup>](https://www.w3.org/TR/act-rules-format/#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 [<sup>?</sup>](https://www.w3.org/TR/act-rules-format/#accessibility-requirements-mapping)\n\n* [ActivityPub requirement f965e989-4084-4f9d-9119-6a7ea13bcb64](https://socialweb.coop/activitypub/behaviors/f965e989-4084-4f9d-9119-6a7ea13bcb64/) - The likes collection MUST be either an OrderedCollection or a Collection\n * Required for Conformance to [ActivityPub][activitypub]\n * Outcome Mapping\n * when every test target has outcome `passed`, the requirement is satisfied by the test subject\n * when any test target has outcome `failed`, the requirement is not satisfied by the test subject\n * when any test target has outcome `inapplicable`, further testing is needed to determine requirement satisfaction\n\n## Issues [<sup>?</sup>](https://www.w3.org/TR/act-rules-format/issues-list)\n\n## Change Log\n\n* 2023-12-06T06:48:14.689Z: init\n* 2023-12-18T04:33:22.670Z: add more example cases that were useful for maximizing implementation code coverage\n\n[activitypub]: https://www.w3.org/TR/activitypub/\n", "name": "An ActivityPub Object `likes` Collection Must be a Collection", "description": "tests whether an ActivityPub Object has a likes collection with an appropriate Collection type", "slug": "likes-collection-must-be-a-collection", "inapplicableCases": [ { "name": "inapplicable example 1", "input": { "object": "1" }, "result": { "outcome": "inapplicable" } }, { "name": "inapplicble example 2 - object has no likes property", "input": { "object": "\n { \"foo\": \"bar\" }\n " }, "result": { "outcome": "inapplicable" } }, { "name": "inapplicable example 3 - html object", "input": { "object": "<!doctype html>hi" }, "result": { "outcome": "inapplicable" } } ], "passedCases": [ { "name": "passed example 1", "input": { "object": "\n {\n \"likes\": {\n \"type\": \"Collection\"\n }\n }\n " }, "result": { "outcome": "passed" } }, { "name": "passed example 2", "input": { "object": "\n {\n \"likes\": {\n \"type\": [\"FancyCollection\", \"OrderedCollection\"]\n }\n }\n " }, "result": { "outcome": "passed" } } ], "failedCases": [ { "name": "failed example 1", "input": { "object": "\n {\n \"likes\": 1\n }\n " }, "result": { "outcome": "failed" } }, { "name": "failed example 2", "input": { "object": "\n {\n \"likes\": {}\n }\n " }, "result": { "outcome": "failed" } }, { "name": "failed example 3", "input": { "object": "\n {\n \"likes\": {\n \"type\": [\"Link\"]\n }\n }\n " }, "result": { "outcome": "failed" } } ], "uuid": "200b9bc8-aae3-46f2-a6ab-5366042c0f6e", "isPartOf": [ "https://socialweb.coop/activitypub/test-cases/" ], "requirementReference": [ { "id": "urn:uuid:f965e989-4084-4f9d-9119-6a7ea13bcb64", "url": "https://socialweb.coop/activitypub/behaviors/f965e989-4084-4f9d-9119-6a7ea13bcb64/" } ] }