Skip to content

Commit be38acd

Browse files
Add tests for event parsing.
Also fix some logic errors.
1 parent 712f863 commit be38acd

File tree

2 files changed

+207
-5
lines changed

2 files changed

+207
-5
lines changed

webapp/src/Serializer/Shadowing/EventDenormalizer.php

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class EventDenormalizer implements DenormalizerInterface, SerializerAwareInterfa
3030
* data: array{id: string}|array<array{id: string}>|null
3131
* } $data
3232
* @param array{api_version?: string} $context
33+
*
3334
* @return Event<EventData>
3435
*
3536
* @throws ExceptionInterface
@@ -51,24 +52,36 @@ public function denormalize(
5152
$eventType = EventType::fromString($data['type']);
5253
if ($this->getEventFeedFormat($data, $context) === EventFeedFormat::Format_2022_07) {
5354
$operation = isset($data['data']) ? Operation::CREATE : Operation::DELETE;
54-
if (!isset($data['data'][0])) {
55+
if (isset($data['data']) && !isset($data['data'][0])) {
5556
$data['data'] = [$data['data']];
5657
}
57-
$id = $operation === Operation::DELETE ? $data['id'] : $data['data'][0]['id'] ?? null;
58+
if ($operation === Operation::CREATE && count($data['data']) === 1) {
59+
$id = $data['data'][0]['id'];
60+
} elseif ($operation === Operation::DELETE) {
61+
$id = $data['id'];
62+
} else {
63+
$id = null;
64+
}
5865
return new Event(
5966
$data['token'] ?? null,
6067
$eventType,
6168
$operation,
6269
$id,
63-
$this->serializer->denormalize($data['data'], EventData::class . '[]', $format, $context + ['event_type' => $eventType]),
70+
isset($data['data']) ? $this->serializer->denormalize($data['data'], EventData::class . '[]', $format, $context + ['event_type' => $eventType]) : [],
6471
);
6572
} else {
73+
$operation = Operation::from($data['op']);
74+
if ($operation === Operation::DELETE) {
75+
$eventData = [];
76+
} else {
77+
$eventData = [$this->serializer->denormalize($data['data'], EventData::class, $format, $context + ['event_type' => $eventType])];
78+
}
6679
return new Event(
6780
$data['id'] ?? null,
6881
$eventType,
69-
Operation::from($data['op']),
82+
$operation,
7083
$data['data']['id'],
71-
[$this->serializer->denormalize($data['data'], EventData::class, $format, $context + ['event_type' => $eventType])],
84+
$eventData,
7285
);
7386
}
7487
}
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App\Tests\Unit\Serializer\Shadowing;
4+
5+
use App\DataTransferObject\Shadowing\Event;
6+
use App\DataTransferObject\Shadowing\EventType;
7+
use App\DataTransferObject\Shadowing\LanguageEvent;
8+
use App\DataTransferObject\Shadowing\Operation;
9+
use App\DataTransferObject\Shadowing\SubmissionEvent;
10+
use Generator;
11+
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
12+
use Symfony\Component\Serializer\SerializerInterface;
13+
14+
class EventDenormalizerTest extends KernelTestCase
15+
{
16+
/**
17+
* @dataProvider provideDenormalize
18+
*/
19+
public function testDenormalizeUseContext(
20+
mixed $data,
21+
array $context,
22+
?string $expectedId,
23+
EventType $expectedType,
24+
Operation $expectedOperation,
25+
?string $expectedObjectId,
26+
array $expectedData
27+
) {
28+
$serializer = $this->getcontainer()->get(SerializerInterface::class);
29+
$event = $serializer->denormalize($data, Event::class, 'json', $context);
30+
self::assertEquals($expectedId, $event->id);
31+
self::assertEquals($expectedType, $event->type);
32+
self::assertEquals($expectedOperation, $event->operation);
33+
self::assertEquals($expectedObjectId, $event->objectId);
34+
self::assertEquals($expectedData, $event->data);
35+
}
36+
37+
/**
38+
* @dataProvider provideDenormalize
39+
*/
40+
public function testDenormalizeDoNotUseContext(
41+
mixed $data,
42+
array $context,
43+
?string $expectedId,
44+
EventType $expectedType,
45+
Operation $expectedOperation,
46+
?string $expectedObjectId,
47+
array $expectedData
48+
) {
49+
$serializer = $this->getcontainer()->get(SerializerInterface::class);
50+
$event = $serializer->denormalize($data, Event::class, 'json', ['api_version' => null]);
51+
self::assertEquals($expectedId, $event->id);
52+
self::assertEquals($expectedType, $event->type);
53+
self::assertEquals($expectedOperation, $event->operation);
54+
self::assertEquals($expectedObjectId, $event->objectId);
55+
self::assertEquals($expectedData, $event->data);
56+
}
57+
58+
public function provideDenormalize(): Generator
59+
{
60+
yield '2022-07 format, create/update single' => [
61+
[
62+
'type' => 'submissions',
63+
'token' => 'sometoken',
64+
'data' => [
65+
'id' => '123',
66+
'language_id' => 'cpp',
67+
'problem_id' => 'A',
68+
'team_id' => '1',
69+
'time' => '456',
70+
'files' => [],
71+
],
72+
],
73+
['api_version' => '2022-07'],
74+
'sometoken',
75+
EventType::SUBMISSIONS,
76+
Operation::CREATE,
77+
'123',
78+
[
79+
new SubmissionEvent(
80+
id: '123',
81+
languageId: 'cpp',
82+
problemId: 'A',
83+
teamId: '1',
84+
time: '456',
85+
entryPoint: null,
86+
files: []
87+
),
88+
],
89+
];
90+
yield '2022-07 format, create/update multiple' => [
91+
[
92+
'type' => 'languages',
93+
'token' => 'anothertoken',
94+
'data' => [
95+
['id' => 'cpp'],
96+
['id' => 'java'],
97+
],
98+
],
99+
['api_version' => '2022-07'],
100+
'anothertoken',
101+
EventType::LANGUAGES,
102+
Operation::CREATE,
103+
null,
104+
[
105+
new LanguageEvent(id: 'cpp'),
106+
new LanguageEvent(id: 'java'),
107+
],
108+
];
109+
yield '2022-07 format, delete' => [
110+
[
111+
'type' => 'problems',
112+
'id' => '987',
113+
'token' => 'yetanothertoken',
114+
'data' => null,
115+
],
116+
['api_version' => '2022-07'],
117+
'yetanothertoken',
118+
EventType::PROBLEMS,
119+
Operation::DELETE,
120+
'987',
121+
[],
122+
];
123+
yield '2020-03 format, create' => [
124+
[
125+
'id' => 'sometoken',
126+
'type' => 'submissions',
127+
'op' => 'create',
128+
'data' => [
129+
'id' => '123',
130+
'language_id' => 'cpp',
131+
'problem_id' => 'A',
132+
'team_id' => '1',
133+
'time' => '456',
134+
'files' => [],
135+
],
136+
],
137+
['api_version' => '2020-03'],
138+
'sometoken',
139+
EventType::SUBMISSIONS,
140+
Operation::CREATE,
141+
'123',
142+
[
143+
new SubmissionEvent(
144+
id: '123',
145+
languageId: 'cpp',
146+
problemId: 'A',
147+
teamId: '1',
148+
time: '456',
149+
entryPoint: null,
150+
files: []
151+
),
152+
],
153+
];
154+
yield '2020-03 format, update' => [
155+
[
156+
'id' => 'anothertoken',
157+
'type' => 'languages',
158+
'op' => 'update',
159+
'data' => [
160+
'id' => 'cpp',
161+
],
162+
],
163+
['api_version' => '2020-03'],
164+
'anothertoken',
165+
EventType::LANGUAGES,
166+
Operation::UPDATE,
167+
'cpp',
168+
[
169+
new LanguageEvent(id: 'cpp'),
170+
],
171+
];
172+
yield '2020-03 format, delete' => [
173+
[
174+
'id' => 'yetanothertoken',
175+
'type' => 'problems',
176+
'op' => 'delete',
177+
'data' => [
178+
'id' => '987',
179+
],
180+
],
181+
['api_version' => '2020-03'],
182+
'yetanothertoken',
183+
EventType::PROBLEMS,
184+
Operation::DELETE,
185+
'987',
186+
[],
187+
];
188+
}
189+
}

0 commit comments

Comments
 (0)