update to PHP-8.1
[m6w6/seekat] / tests / ContentTypeTest.php
1 <?php
2
3 use seekat\API\ContentType;
4 use http\Header;
5 use http\Message\Body;
6
7 class ContentTypeTest extends BaseTest
8 {
9 /**
10 * @group testdox
11 * @dataProvider provideAPI
12 */
13 function testIsAbleToApplyVersionedContentTypeToApi($api) {
14 $api = (new ContentType($api->getVersion(), "json"))->apply($api);
15 $this->assertEquals(
16 $this->getVersionedContentType("json")->value,
17 $api->export()["headers"]["Accept"]);
18
19 $api = (new ContentType($api->getVersion(), "+raw"))->apply($api);
20 $this->assertEquals(
21 $this->getVersionedContentType("+raw")->value,
22 $api->export()["headers"]["Accept"]);
23
24 $api = (new ContentType($api->getVersion(), ".html"))->apply($api);
25 $this->assertEquals(
26 $this->getVersionedContentType(".html")->value,
27 $api->export()["headers"]["Accept"]);
28 }
29
30 /**
31 * @group testdox
32 * @dataProvider provideAPI
33 */
34 function testIsAbleToApplyBasicContentTypeToApi($api) {
35 $api = (new ContentType($api->getVersion(), "text/plain"))->apply($api);
36 $this->assertEquals("text/plain", $api->export()["headers"]["Accept"]);
37 }
38
39 /**
40 * @group testdox
41 */
42 function testAllowsToRegisterAndUnregisterContentTypeHandlers() {
43 $this->assertFalse(ContentType::registered("foobar"));
44 ContentType::register(new class implements ContentType\Handler {
45 function types() : array {
46 return ["foobar"];
47 }
48 function encode($data): Body {
49 return new Body;
50 }
51 function decode(Body $body) : string {
52 return (string) $body;
53 }
54 });
55 $this->assertTrue(ContentType::registered("foobar"));
56 ContentType::unregister("foobar");
57 $this->assertFalse(ContentType::registered("foobar"));
58 }
59
60 /**
61 * @group testdox
62 */
63 function testAcceptsContentTypeHeader() {
64 $ct = new ContentType;
65 $ct->setContentTypeHeader(new Header("Content-Type", "TitleCase"));
66 $this->assertSame("TitleCase", $ct->getType());
67 $ct->setContentTypeHeader(new Header("content-type", "lowercase"));
68 $this->assertSame("lowercase", $ct->getType());
69 }
70
71 /**
72 * @group testdox
73 */
74 function testDoesNotAcceptNonContentTypeHeader() {
75 $this->expectException(\seekat\Exception\InvalidArgumentException::class);
76 (new ContentType)->setContentTypeHeader(new Header("ContentType"));
77 }
78
79 /**
80 * @group testdox
81 */
82 function testThrowsOnUnknownContentType() {
83 $this->expectException(\seekat\Exception\UnexpectedValueException::class);
84 $ct = new ContentType(3, "foo");
85 $ct->decode((new Body)->append("foo"));
86 }
87
88 /**
89 * @group testdox
90 */
91 function testHandlesJson() {
92 $this->assertTrue(ContentType::registered("json"));
93 $ct = new ContentType(3, "application/json");
94 $result = $ct->decode((new Body())->append("[1,2,3]"));
95 $this->assertEquals([1, 2, 3], $result);
96 return $ct;
97 }
98
99 /**
100 * @group testdox
101 * @depends testHandlesJson
102 */
103 function testThrowsOnInvalidJson(ContentType $ct) {
104 $this->expectException(\seekat\Exception\UnexpectedValueException::class);
105 $ct->decode((new Body)->append("yaml:\n - data"));
106 }
107
108 /**
109 * @group testdox
110 */
111 function testHandlesBase64() {
112 $this->assertTrue(ContentType::registered("base64"));
113 $ct = new ContentType(3,"base64");
114 $result = $ct->decode((new Body())->append(base64_encode("This is a test")));
115 $this->assertEquals("This is a test", $result);
116 return $ct;
117 }
118
119 /**
120 * @group testdox
121 * @depends testHandlesBase64
122 */
123 function testThrowsOnInvalidBase64(ContentType $ct) {
124 $this->expectException(\seekat\Exception\UnexpectedValueException::class);
125 $ct->decode((new Body)->append("[1,2,3]"));
126 }
127
128 /**
129 * @group testdox
130 */
131 function testHandlesOctetStream() {
132 $this->assertTrue(ContentType::registered("application/octet-stream"));
133 $ct = new ContentType(3,"application/octet-stream");
134 $result = $ct->decode((new Body)->append("This is a test"));
135 $this->assertIsResource($result);
136 rewind($result);
137 $this->assertEquals("This is a test", stream_get_contents($result));
138 }
139
140 /**
141 * @group testdox
142 */
143 function testHandlesData() {
144 $this->assertTrue(ContentType::registered("text/plain"));
145 $ct = new ContentType(3,"text/plain");
146 $result = $ct->decode((new Body)->append("This is a test"));
147 $this->assertIsString($result);
148 $this->assertEquals("This is a test", $result);
149 }
150
151 /**
152 * @param string $type
153 * @return Header Content-Type header
154 */
155 private function getVersionedContentType($type) {
156 switch ($type[0]) {
157 case ".":
158 case "+":
159 case "":
160 break;
161 default:
162 $type = ".$type";
163 }
164 return new Header("Content-Type",
165 sprintf("application/vnd.github.v3%s", $type));
166 }
167 }