As a tool builder I want to be able to change aliases of an item so that work in my tool can be saved back to Wikidata.
PATCH /entities/items/{item_id}/aliases
**Acceptance criteria: **
- The request contains a JSON body with a mandatory `patch` key containing a JSON Patch document plus optional metadata: `tags`, `bot`, `comment`.
- Response body containing the updated aliases data, using the similar structure as `GET /entities/items/{item_id}/aliases`.
- Handle HTTP conditional request headers as in PATCH /entities/items/{item_id}/labels **(double check)**
- Handle user authentication/authorization like in PATCH /entities/items/{item_id}/labels
- duplicate aliases are not allowed per language
- cross-language "collision detection" does not apply for aliases
- All edit data is validated
Autocomments:
* should mimic the `wbeditentity` behavior when editing aliases:
* If the change results in changing aliases in not more than 50 languages: `/* wbeditentity-update-languages-short:0||LANGS */`
* If the change results in changing aliases in 51 or more languages: `/* wbeditentity-update-languages:0||LANG_COUNT */`
* where `LANGS` is a comma separated list of alphabeticall-sorted language codes of relevant languages (e.g. `de, en, es, fi, fr, it`). `LANG_COUNT` is a number of languages with changed aliases
* the boundary number of 50 languages is defined in `ChangedLanguagesCounter::SHORTENED_SUMMARY_MAX_EDIT` constant (not configurable)
Error cases considered:
<table>
<tr>
<th>error type</th>
<th> HTTP Response code</th>
<th>Response content</th>
</tr>
<tr>
<td>Item with the given ID does not exist</td>
<td>404</td>
<td>
`"code": "item-not-found",`
`"message": "Could not find a an item with the ID: '{item_id}'"`
</td>
</tr>
<tr>
<td>ID provided is not a valid item ID</td>
<td>400</td>
<td>
` "code": "invalid-property-id",`
`"message": "Not a valid item ID: '{item_id}'"`
</td>
</tr>
<tr>
<td>Invalid JSON patch (general error)</td>
<td>400</td>
<td>
`"code": "invalid-patch"`
`"message": "The provided patch is invalid"`
</td>
</tr>
<tr>
<td>incorrect JSON patch operation</td>
<td>400</td>
<td>
`"code": "invalid-patch-operation"`
`"message": "Incorrect JSON patch operation: '<op>'"`
`"context": { "operation": <operation_object> }`
</td>
</tr>
<tr>
<td>
invalid field type in JSON patch
(either of `op`, `path`, `from` is not a string)
</td>
<td>400</td>
<td>
`"code": "invalid-patch-field-type"`
`"message": "The value of '<field>' must be of type string"`
`"context": { "operation": <operation_object>, "field": <field> }`
</td>
</tr>
<tr>
<td>
missing mandatory field in JSON patch
(`op`, `path`, `value`, also `from` on copy/move patches)
</td>
<td>400</td>
<td>
`"code": "missing-json-patch-field"`
`"message": "Missing '<field>' in JSON patch"`
`"context": { "operation": <operation_object>, "field": <field> }`
</td>
</tr>
<tr>
<td>Target of JSON Patch not found on the object</td>
<td>409</td>
<td>
`"code": "patch-target-not-found",`
`"message": "Target '<target>' not found on the resource",`
`"context": {`
` "operation": <operation_object>,`
` "field": <path>`
`}`
</td>
</tr>
<tr>
<td>JSON Patch test operation failed</td>
<td>409</td>
<td>
`"code": "patch-test-failed",`
`"message": "Test operation in the provided patch failed. At path '{path}' expected '{expected}', actual: '{actual}'",`
`"context": {`
` "operation": <operation_object>,`
` "actual-value": <actual>`
`}`
</td>
</tr>
<tr>
<td>After changes an invalid language code is used</td>
<td>422</td>
<td>
`"code": "patched-alias-invalid-language-code"`
`"message": "Not a valid language code '{language_code}' in changed aliases"`
`"context": {`
` "language": <language_code>`
`}`
</td>
</tr>
<tr>
<td>After changes an alias is invalid (empty, too long)</td>
<td>422</td>
<td>
`"code": "patched-alias-empty"/"patched-alias-too-long"`
`"message": "Changed alias for '{lang_code}' cannot be empty" / "Changed alias for '{lang_code}' must not be more than '{limit}' characters long"`
`"context": {`
` "language": <language_code>`
` "value": <alias>` (too long alias case only)
` "character-limit": <limit>` (too long alias case only)
`}`
</td>
</tr>
<tr>
<td>Duplicates in aliases not allowed </td>
<td>422</td>
<td>
`"code": "patched-duplicate-alias"`
`"message": "Aliases in language {language_code} contain duplicate alias: '{alias}' "`
`"context": {`
`"alias": <alias>
"language": <language_code>`
`}`
</td>
</tr>
<tr>
<td>Invalid edit tag</td>
<td>400</td>
<td>
`{ "code": "invalid-edit-tag", "message": "Invalid MediaWiki tag: {tag}" }`
</td>
</tr>
<tr>
<td>Comment too long</td>
<td>400</td>
<td>
`{"code": "comment-too-long", "message": "Comment must not be longer than {limit} characters"}`
</td>
</tr>
</table>
Additional notes:
* How Action API handles it (somewhat): https://www.wikidata.org/w/api.php?action=help&modules=wbeditentity