Skip to content

Commit 0cc7059

Browse files
committed
Add encoding tests for API framework
Add tests that check that the API framework is able to handle various character classes. This also serves to document current behaviour.
1 parent 1e4c2d2 commit 0cc7059

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
@api
2+
Feature: API (de)serialization using api_ping
3+
4+
# These tests use the api_ping endpoint (only available in development environments)
5+
# to test how strings with different encodings are passed to and/from API endpoints.
6+
# This is meant to test behaviour of the common API code in util/api.py (in combination
7+
# with iRODS and PRC).
8+
9+
Scenario Outline: The object echo endpoint returns <case> unchanged
10+
Given user technicaladmin is authenticated
11+
When the ping API is queried with the "<case>" payload
12+
Then the response status code is "200"
13+
And the ping response returns the "<case>" payload unchanged
14+
15+
Examples:
16+
| case |
17+
| empty_string |
18+
| ascii_only_letters |
19+
| ascii_with_numbers |
20+
| ascii_with_punctuation |
21+
| ascii_with_newline |
22+
| ascii_long_10k |
23+
| non_ascii_letters |
24+
| control_chars |
25+
| cjk |
26+
| emoji_astral |
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# coding=utf-8
2+
"""Ping/echo API feature tests.
3+
4+
These tests document how the API framework in util/api.py (de)serializes
5+
various character encodings, end-to-end through the normal API request path
6+
(python-irodsclient, iRODS and back).
7+
"""
8+
9+
__copyright__ = 'Copyright (c) 2026, Utrecht University'
10+
__license__ = 'GPLv3, see LICENSE'
11+
12+
from pytest_bdd import (
13+
parsers,
14+
scenarios,
15+
then,
16+
when,
17+
)
18+
19+
from conftest import api_request
20+
21+
scenarios('../../features/api/api_ping.feature')
22+
23+
# String payloads echoed back verbatim by api_ping
24+
STRING_PAYLOADS = {
25+
"empty_string": "",
26+
"ascii_only_letters": "Hello world",
27+
"ascii_with_numbers": "The 39 steps",
28+
"ascii_with_punctuation": "Hello `~!@#$%^&*()-_=+;:'\"\\|<>,.?/",
29+
"ascii_with_newline": "Line 1\nLine 2",
30+
"ascii_long_10k": 9000 * "a",
31+
"non_ascii_letters": "blåbær smör mjólk brauð",
32+
"control_chars": "tab\there newline\nreturn\rnuli\0bell\a",
33+
"cjk": "日本語 한국어", # Kanji and Korean Unicode
34+
"emoji_astral": "\U0001f600\U0001f389", # Unicode outside basic multilingual plane (BMP)
35+
}
36+
37+
38+
@when(parsers.parse('the ping API is queried with the "{case}" payload'), target_fixture="api_response")
39+
def ping_query(user, case):
40+
return api_request(user, "ping", {"x": STRING_PAYLOADS[case]})
41+
42+
43+
@then(parsers.parse('the ping response returns the "{case}" payload unchanged'))
44+
def ping_response_echoes(api_response, case):
45+
_, body = api_response
46+
payload = STRING_PAYLOADS[case]
47+
48+
assert body["status"] == "ok", body
49+
assert body["data"] == payload
50+
51+
52+
@then(parsers.parse('the ping response is an error named "{name}"'))
53+
def ping_response_error(api_response, name):
54+
_, body = api_response
55+
assert body["status"] == "error_" + name, body

0 commit comments

Comments
 (0)