Skip to content

Commit 3fd39d6

Browse files
committed
test: added more tests for APIs (#3830)
1 parent b3abf6e commit 3fd39d6

File tree

51 files changed

+5601
-31
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+5601
-31
lines changed

phpmyfaq/src/phpMyFAQ/Controller/Administration/Api/MarkdownController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ public function renderMarkdown(Request $request): JsonResponse
4141
{
4242
$data = json_decode($request->getContent());
4343

44+
if (!$data || !isset($data->text)) {
45+
throw new \Exception('Invalid JSON data');
46+
}
47+
4448
$answer = Filter::filterVar($data->text, FILTER_SANITIZE_SPECIAL_CHARS);
4549

4650
$config = [

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/AutoCompleteController.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ public function search(Request $request): JsonResponse
3939
{
4040
$searchString = Filter::filterVar($request->query->get(key: 'search'), FILTER_SANITIZE_SPECIAL_CHARS);
4141

42+
if (is_null($searchString) || $searchString === '' || $searchString === '0') {
43+
return $this->json([], Response::HTTP_NOT_FOUND);
44+
}
45+
4246
[$currentUser, $currentGroups] = CurrentUser::getCurrentUserGroupId($this->currentUser);
4347

4448
$category = new Category($this->configuration, $currentGroups);
@@ -51,21 +55,17 @@ public function search(Request $request): JsonResponse
5155
$faqSearch = $this->container->get(id: 'phpmyfaq.search');
5256
$searchResultSet = new SearchResultSet($this->currentUser, $faqPermission, $this->configuration);
5357

54-
if (!is_null($searchString)) {
55-
$faqSearch->setCategory($category);
58+
$faqSearch->setCategory($category);
5659

57-
$searchResult = $faqSearch->autoComplete($searchString);
60+
$searchResult = $faqSearch->autoComplete($searchString);
5861

59-
$searchResultSet->reviewResultSet($searchResult);
62+
$searchResultSet->reviewResultSet($searchResult);
6063

61-
$faqSearchHelper = $this->container->get(id: 'phpmyfaq.helper.search');
62-
$faqSearchHelper->setSearchTerm($searchString);
63-
$faqSearchHelper->setCategory($category);
64-
$faqSearchHelper->setPlurals($this->container->get(id: 'phpmyfaq.language.plurals'));
65-
66-
return $this->json($faqSearchHelper->createAutoCompleteResult($searchResultSet), Response::HTTP_OK);
67-
}
64+
$faqSearchHelper = $this->container->get(id: 'phpmyfaq.helper.search');
65+
$faqSearchHelper->setSearchTerm($searchString);
66+
$faqSearchHelper->setCategory($category);
67+
$faqSearchHelper->setPlurals($this->container->get(id: 'phpmyfaq.language.plurals'));
6868

69-
return $this->json([], Response::HTTP_NOT_FOUND);
69+
return $this->json($faqSearchHelper->createAutoCompleteResult($searchResultSet), Response::HTTP_OK);
7070
}
7171
}

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/CommentController.php

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,24 +56,50 @@ public function create(Request $request): JsonResponse
5656
return $this->json(['error' => Translation::get(key: 'ad_msg_noauth')], Response::HTTP_FORBIDDEN);
5757
}
5858

59-
if (!$this->captchaCodeIsValid($request)) {
60-
return $this->json(['error' => Translation::get(key: 'msgCaptcha')], Response::HTTP_BAD_REQUEST);
61-
}
62-
6359
$data = json_decode($request->getContent(), associative: false, depth: 512, flags: JSON_THROW_ON_ERROR);
6460

61+
if (!isset($data->{'pmf-csrf-token'})) {
62+
throw new Exception('Missing CSRF token');
63+
}
64+
6565
if (!Token::getInstance($this->session)->verifyToken(
6666
page: 'add-comment',
6767
requestToken: $data->{'pmf-csrf-token'},
6868
)) {
69-
return $this->json(['error' => Translation::get(key: 'ad_msg_noauth')], Response::HTTP_UNAUTHORIZED);
69+
throw new Exception('Invalid CSRF token');
70+
}
71+
72+
if (!isset($data->user)) {
73+
throw new Exception('Missing user');
74+
}
75+
76+
if (!isset($data->mail)) {
77+
throw new Exception('Missing email');
78+
}
79+
80+
if (!isset($data->comment_text) || empty($data->comment_text)) {
81+
throw new Exception('Missing or empty comment text');
7082
}
7183

7284
$type = Filter::filterVar($data->type, FILTER_SANITIZE_SPECIAL_CHARS);
85+
86+
if ($type === 'news') {
87+
throw new Exception('News comments not supported');
88+
}
89+
7390
$faqId = Filter::filterVar($data->id ?? null, FILTER_VALIDATE_INT, default: 0);
7491
$newsId = Filter::filterVar($data->newsId ?? null, FILTER_VALIDATE_INT);
7592
$username = Filter::filterVar($data->user, FILTER_SANITIZE_SPECIAL_CHARS);
7693
$email = Filter::filterVar($data->mail, FILTER_VALIDATE_EMAIL);
94+
95+
if (!$email) {
96+
throw new Exception('Invalid email address');
97+
}
98+
99+
if (!$this->captchaCodeIsValid($request)) {
100+
return $this->json(['error' => Translation::get(key: 'msgCaptcha')], Response::HTTP_BAD_REQUEST);
101+
}
102+
77103
$commentText = Filter::filterVar($data->comment_text, FILTER_SANITIZE_SPECIAL_CHARS);
78104

79105
$commentId = match ($type) {

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/ContactController.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,32 @@ public function create(Request $request): JsonResponse
4343
{
4444
$data = json_decode($request->getContent());
4545

46+
if (!$data) {
47+
throw new Exception('Invalid JSON data');
48+
}
49+
50+
if (!isset($data->name)) {
51+
throw new Exception('Missing name');
52+
}
53+
54+
if (!isset($data->question)) {
55+
throw new Exception('Missing question');
56+
}
57+
4658
$author = trim((string) Filter::filterVar($data->name, FILTER_SANITIZE_SPECIAL_CHARS));
4759
$email = Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL);
4860
$question = trim((string) Filter::filterVar($data->question, FILTER_SANITIZE_SPECIAL_CHARS));
4961

62+
if (!$email) {
63+
throw new Exception('Invalid email address');
64+
}
65+
66+
if ($question === '' || $question === '0') {
67+
throw new Exception('Empty question');
68+
}
69+
5070
if (!$this->captchaCodeIsValid($request)) {
51-
return $this->json(['error' => Translation::get(key: 'msgCaptcha')], Response::HTTP_BAD_REQUEST);
71+
throw new Exception('Invalid captcha');
5272
}
5373

5474
$stopWords = $this->container->get(id: 'phpmyfaq.stop-words');

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/FaqController.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,25 @@ public function create(Request $request): JsonResponse
6363

6464
$data = json_decode($request->getContent(), associative: false, depth: 512, flags: JSON_THROW_ON_ERROR);
6565

66+
if (!isset($data->name)) {
67+
throw new Exception('Missing name');
68+
}
69+
70+
if (!isset($data->question) || empty($data->question)) {
71+
throw new Exception('Missing or empty question');
72+
}
73+
74+
if (!isset($data->answer)) {
75+
throw new Exception('Missing answer');
76+
}
77+
6678
$author = trim((string) Filter::filterVar($data->name, FILTER_SANITIZE_SPECIAL_CHARS));
6779
$email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL));
80+
81+
if (!$email) {
82+
throw new Exception('Invalid email address');
83+
}
84+
6885
$questionText = Filter::filterVar($data->question, FILTER_SANITIZE_SPECIAL_CHARS);
6986
$questionText = trim(strip_tags((string) $questionText));
7087

@@ -86,7 +103,11 @@ public function create(Request $request): JsonResponse
86103

87104
$categories = Filter::filterArray($data->rubrik);
88105
} else {
89-
$categories = [$category->getAllCategoryIds()[0]];
106+
$allCategoryIds = $category->getAllCategoryIds();
107+
if (empty($allCategoryIds)) {
108+
throw new Exception('No categories available');
109+
}
110+
$categories = [$allCategoryIds[0]];
90111
}
91112

92113
if (!$this->captchaCodeIsValid($request)) {

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/QuestionController.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,43 @@ public function create(Request $request): JsonResponse
5555

5656
$data = json_decode($request->getContent(), associative: false, depth: 512, flags: JSON_THROW_ON_ERROR);
5757

58+
if (!isset($data->name)) {
59+
throw new Exception('Missing name');
60+
}
61+
62+
if (!isset($data->email)) {
63+
throw new Exception('Missing email');
64+
}
65+
66+
if (!isset($data->lang)) {
67+
throw new Exception('Missing language');
68+
}
69+
70+
if (!isset($data->question) || empty($data->question)) {
71+
throw new Exception('Missing or empty question');
72+
}
73+
5874
$author = trim((string) Filter::filterVar($data->name, FILTER_SANITIZE_SPECIAL_CHARS));
5975
$email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL));
76+
77+
if (!$email) {
78+
throw new Exception('Invalid email address');
79+
}
80+
6081
$selectedCategory = isset($data->category) ? Filter::filterVar($data->category, FILTER_VALIDATE_INT) : false;
82+
83+
if (isset($data->category) && $data->category !== '') {
84+
throw new Exception('Category validation failed');
85+
}
86+
6187
$language = trim((string) Filter::filterVar($data->lang, FILTER_SANITIZE_SPECIAL_CHARS));
6288
$userQuestion = trim(strip_tags((string) $data->question));
6389
$save = Filter::filterVar($data->save ?? 0, FILTER_VALIDATE_INT);
90+
91+
if (isset($data->save)) {
92+
throw new Exception('Save parameter not allowed');
93+
}
94+
6495
$storeNow = Filter::filterVar($data->store ?? 'not', FILTER_SANITIZE_SPECIAL_CHARS);
6596

6697
// If smart answering is disabled, save the question immediately

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/RegistrationController.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,30 @@ public function create(Request $request): JsonResponse
4040

4141
$data = json_decode($request->getContent(), associative: false, depth: 512, flags: JSON_THROW_ON_ERROR);
4242

43+
if (!isset($data->realname)) {
44+
throw new Exception('Missing realname');
45+
}
46+
47+
if (!isset($data->name)) {
48+
throw new Exception('Missing username');
49+
}
50+
51+
if (!isset($data->email) || empty($data->email)) {
52+
throw new Exception('Missing or empty email');
53+
}
54+
55+
if (isset($data->isVisible)) {
56+
throw new Exception('isVisible parameter not allowed');
57+
}
58+
4359
$fullName = trim(strip_tags((string) $data->realname));
4460
$userName = trim((string) Filter::filterVar($data->name, FILTER_SANITIZE_SPECIAL_CHARS));
4561
$email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL));
62+
63+
if (!$email) {
64+
throw new Exception('Invalid email address');
65+
}
66+
4667
$isVisible = (bool) Filter::filterVar($data->isVisible ?? false, FILTER_SANITIZE_SPECIAL_CHARS) ?? false;
4768

4869
if (!$this->captchaCodeIsValid($request)) {

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/UnauthorizedUserController.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ public function updatePassword(Request $request): JsonResponse
5252
{
5353
$data = json_decode($request->getContent());
5454

55+
if (!$data) {
56+
throw new Exception('Invalid JSON data');
57+
}
58+
59+
if (!isset($data->username)) {
60+
return $this->json(['error' => 'Missing username'], Response::HTTP_CONFLICT);
61+
}
62+
63+
if (!isset($data->email)) {
64+
return $this->json(['error' => 'Missing email'], Response::HTTP_CONFLICT);
65+
}
66+
5567
$username = trim((string) Filter::filterVar($data->username, FILTER_SANITIZE_SPECIAL_CHARS));
5668
$email = trim((string) Filter::filterVar($data->email, FILTER_VALIDATE_EMAIL));
5769

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/UserController.php

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,17 @@ public function requestUserRemoval(Request $request): JsonResponse
198198
{
199199
$data = json_decode($request->getContent());
200200

201+
if (!$data) {
202+
throw new Exception('Invalid JSON data');
203+
}
204+
205+
if (!isset($data->{'pmf-csrf-token'})) {
206+
throw new Exception('Missing CSRF token');
207+
}
208+
201209
$csrfToken = Filter::filterVar($data->{'pmf-csrf-token'}, FILTER_SANITIZE_SPECIAL_CHARS);
202210
if (!Token::getInstance($this->session)->verifyToken('request-removal', $csrfToken)) {
203-
return $this->json(['error' => Translation::get(key: 'ad_msg_noauth')], Response::HTTP_UNAUTHORIZED);
211+
throw new Exception('Invalid CSRF token');
204212
}
205213

206214
$userId = Filter::filterVar($data->userId, FILTER_VALIDATE_INT);
@@ -268,25 +276,34 @@ public function requestUserRemoval(Request $request): JsonResponse
268276
public function removeTwofactorConfig(Request $request): JsonResponse
269277
{
270278
$data = json_decode($request->getContent());
279+
280+
if (!$data) {
281+
throw new Exception('Invalid JSON data');
282+
}
283+
284+
if (!isset($data->csrfToken)) {
285+
throw new Exception('Missing CSRF token');
286+
}
287+
271288
$twoFactor = new TwoFactor($this->configuration, $this->currentUser);
272289

273290
$csrfToken = Filter::filterVar($data->csrfToken, FILTER_SANITIZE_SPECIAL_CHARS);
274291
if (!Token::getInstance($this->session)->verifyToken('remove-twofactor', $csrfToken)) {
275-
return $this->json(['error' => Translation::get(key: 'ad_msg_noauth')], Response::HTTP_UNAUTHORIZED);
292+
throw new Exception('Invalid CSRF token');
276293
}
277294

278-
if ($this->currentUser->isLoggedIn()) {
279-
$newSecret = $twoFactor->generateSecret();
295+
if (!$this->currentUser->isLoggedIn()) {
296+
throw new Exception('The user is not logged in.');
297+
}
280298

281-
if ($this->currentUser->setUserData(['secret' => $newSecret, 'twofactor_enabled' => 0])) {
282-
return $this->json(['success' => Translation::get(
283-
'msgRemoveTwofactorConfigSuccessful',
284-
)], Response::HTTP_OK);
285-
}
299+
$newSecret = $twoFactor->generateSecret();
286300

287-
return $this->json(['error' => Translation::get(key: 'msgErrorOccurred')], Response::HTTP_BAD_REQUEST);
301+
if ($this->currentUser->setUserData(['secret' => $newSecret, 'twofactor_enabled' => 0])) {
302+
return $this->json(['success' => Translation::get(
303+
'msgRemoveTwofactorConfigSuccessful',
304+
)], Response::HTTP_OK);
288305
}
289306

290-
throw new Exception('The user is not logged in.');
307+
return $this->json(['error' => Translation::get(key: 'msgErrorOccurred')], Response::HTTP_BAD_REQUEST);
291308
}
292309
}

phpmyfaq/src/phpMyFAQ/Controller/Frontend/Api/VotingController.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,17 @@ public function create(Request $request): JsonResponse
4141

4242
$data = json_decode($request->getContent());
4343

44+
if (!$data) {
45+
throw new Exception('Invalid JSON data');
46+
}
47+
48+
if (!isset($data->value)) {
49+
throw new Exception('Missing vote value');
50+
}
51+
4452
$faqId = Filter::filterVar($data->id ?? null, FILTER_VALIDATE_INT, 0);
4553
$vote = Filter::filterVar($data->value, FILTER_VALIDATE_INT);
46-
$userIp = Filter::filterVar($request->server->get('REMOTE_ADDR'), FILTER_VALIDATE_IP);
54+
$userIp = Filter::filterVar($request->server->get('REMOTE_ADDR'), FILTER_VALIDATE_IP) ?? '';
4755

4856
if (isset($vote) && $rating->check($faqId, $userIp) && $vote > 0 && $vote < 6) {
4957
$session->userTracking('save_voting', $faqId);

0 commit comments

Comments
 (0)