In the context of client-to-server interactions via Activity submission, ActivityPub says
Servers MUST return a 201 Created HTTP code
This is a Test describing a rule to determine whether an ActivityPub Server is in conformance with the following behaviors required by ActivityPub:
The identifier of this test is 723afcbb-118d-433e-8ab4-560ffca93582
.
The subject of this test is an ActivityPub Server serving activity submission requests for an ActivityPub Outbox.
The Test Subject can be identified by a URI for an ActivityPub Outbox. The ActivityPub Outbox has an id
property and the ActivityPub server is responsible for responding to requests sent to it.
This test requires the following inputs:
outbox
- identifier of an ActivityPub Outbox
null
authorization
- proof of authorization to submit an activity to the outbox identified by input outbox
Authorization
header will be provided in the HTTP request send by this testAuthorization
headersubmission
- ActivityPub message that will be submitted to the Outbox.
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
.This test applies to the server hosting the ActivityPub Outbox identified by input outbox
and that support requests using HTTP method POST
.
If input outbox
is not a URI, outcome is inapplicable
.
If input outbox
URI scheme is not https
or http
, outcome is inapplicable
. (This test may be revised later to handle other URI schemes).
If the server indicates it does not support POST
requests, the test outcome MUST be inapplicable
.
If the server indicates that the provided input includes insufficient proof of authorization to write to the outbox, the test outcome MUST be a CannotTell
.
response
- the HTTP response that is the result of submitting the input submission
to the ActivityPub Outbox identified by input outbox
.
response
from inputs
start a timer with duration from input time
. If the timer reaches zero before this derivation is complete, the whole test outcome is inapplicable
because we weren't able to determine the response
test target within the required time.
let request
be a new HTTP Request whose URI is input outbox
add an http request header to request
whose name is Content-Type
and whose value is application/ld+json; profile="https://www.w3.org/ns/activitystreams"
if input authorization
was provided, add an http request header to request
whose name is Authorization
and whose value is input authorization
let submission
be the input submission
, if provided, otherwise use the json value
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"content": "Say, did you finish reading that book I lent you?"
}
let the http request body of request
be the value of submission
send the HTTP request and await a response
assign the HTTP response to the response
test target
If the status code of response
is 401, the test outcome MUST be a CannotTell
If the status code of response
is 403,
authorization
was provided, the test outcome MAY be Fail
authorization
was not provided) the test outcome MUST be a CannotTell
If the status code of response
is 405 (e.g. 'Method Not Allowed'), the test outcome MUST be inapplicable
POST
, and this test is only applicable to servers that do.response
http status code is 201
If an input submission
is not provided, the test will use an activity based on Example 2 in ActivityPub. If this causes problems, provide an input submission
that will work to produce a 201 response status code and satisfy the requirement being tested.
When interpreting a HTTP 403 response resulting sending a POST request to the input outbox
, this test varies its outcome depending on whether an input authorization
was provided to the test.
A rationale is that HTTP semantics in general defines 403 to mean different things depending on whether authentication credentials were provided in the request:
The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it. A server that wishes to make public why the request has been forbidden can describe that reason in the response content (if any).
If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.
When authentication credentials are provided, and the server returns 403, the test outcome is failed
. This is based on "If authentication credentials were provided in the request, the server considers them insufficient to grant access" from RFC9110 above. failed
seems appropriate for the provided inputs because status 403 communicates that the server received the provided credentials, determined they cannot authorize the request, and that the client SHOULD NOT retrying the request with the same credentials. failed
should draw attention to either flawed authorization logic or, more likely, an inappropriate authorization
input passed to the test.
If no input authorization
is provided, the test outcome is CannotTell
. This is because there isn't enough evidence for another outcome, and it's best for a human to take a look at the rest of the result and decide what to do next.
Server implementers are encouraged to review RFC7235 for HTTP Authentication, which describes a way of responding to requests that lack proof of authorization by using a 401
status code + hints about what authorization is required.
These are test cases for this test itself, i.e. each test case is a set of test inputs and the corresponding test results.
inputs
outbox
https://socialweb.coop/activitypub/testing/utilities/response?status=201`
submission
{
"type": "Create"
}
test targets
response
HTTP/2 201
content-type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"
{}
passed
inputs
outbox
: https://socialweb.coop/activitypub/testing/utilities/response?status=404
submission
{
"type": "Create"
}
test targets
response
:
HTTP/2 404
content-type: text/html; charset=UTF-8
content-length: 153
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.25.2</center>
</body>
</html>
cantTell
outbox
inputs
outbox
: bafybeib5mvfjatmpswc3jnh7ydz4zxe25cm63xp6aafpg3j2awakf63qma
submission
{
"type": "Create"
}
result
inapplicable
outbox
is not a URIinputs
outbox
: https://socialweb.coop/activitypub/testing/utilities/response?status=401
submission
{
"type": "Create"
}
test targets
response
:
HTTP/1.1 401 Forbidden
401
result
cantTell
inputs
outbox
: https://socialweb.coop/activitypub/testing/utilities/response?status=405
submission
{
"type": "Create"
}
test targets
response
:
HTTP/1.1 405 Not Allowed
405
outcome: inapplicable
response
status 405 indicates that requests with method POST
are not supported, so this test does not apply (see 'Applicability')inputs
outbox
: https://socialweb.coop/activitypub/testing/utilities/response?status=403
submission
{
"type": "Create"
}
test targets
response
:
HTTP/1.1 403 Forbidden
403
result
cantTell
inputs
outbox
: https://socialweb.coop/activitypub/testing/utilities/response?status=403
authorization
: Bearer foo
submission
{
"type": "Create"
}
test targets
response
:
HTTP/1.1 403 Forbidden
403
result
failed
outcome
An outcome is a conclusion that comes from evaluating a test on a test subject. An outcome can be one of the three following types:
inapplicable
: No part of the test subject matches the applicabilitypassed
: A test target meets all expectationsfailed
: A test target does not meet all expectationsresponse
has outcome passed
, further testing is needed to determine requirement satisfactionresponse
has outcome failed
, requirement is not satisfiedresponse
has outcome inapplicable
, further testing is needed to determine requirement satisfactionpassed
test case for this
inapplicable
test outcome.