Skip to content

Commit 83117f2

Browse files
committed
chore: improve query performance, add test for currentuserserializer
1 parent 8f093b6 commit 83117f2

File tree

2 files changed

+169
-2
lines changed

2 files changed

+169
-2
lines changed

src/Api/CurrentUserAttributes.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ public function __invoke(CurrentUserSerializer $serializer, User $user, array $a
4141
$loginProvider = LoginProvider::query()
4242
->where('user_id', $user->id)
4343
->orderBy('last_login_at', 'desc')
44-
->pluck('provider')
45-
->first();
44+
->value('provider');
4645

4746
$loginProvider = $loginProvider ?: false;
4847
$this->cache->forever(AbstractOAuthController::SESSION_OAUTH2PROVIDER.'_'.$session->getId(), $loginProvider);
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
/*
4+
* This file is part of fof/oauth.
5+
*
6+
* Copyright (c) FriendsOfFlarum.
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FoF\OAuth\Tests\integration\api;
13+
14+
use Flarum\Extend;
15+
use Flarum\Testing\integration\RetrievesAuthorizedUsers;
16+
use Flarum\Testing\integration\TestCase;
17+
use FoF\Extend\Controllers\AbstractOAuthController;
18+
use Illuminate\Contracts\Cache\Store as Cache;
19+
20+
class CurrentUserAttributesTest extends TestCase
21+
{
22+
use RetrievesAuthorizedUsers;
23+
24+
protected function setUp(): void
25+
{
26+
parent::setUp();
27+
28+
$this->extend(
29+
(new Extend\Csrf)->exemptRoute('login')
30+
);
31+
32+
$this->extension('fof-oauth');
33+
34+
$this->prepareDatabase([
35+
'users' => [
36+
$this->normalUser(),
37+
[
38+
'id' => 3, 'username' => 'oauth_user', 'password' => '$2y$10$LO59tiT7uggl6Oe23o/O6.utnF6ipngYjvMvaxo1TciKqBttDNKim',
39+
'is_email_confirmed' => 1, 'email' => 'oauth_user@example.com',
40+
'joined_at' => '2021-01-01 00:00:00',
41+
],
42+
],
43+
'login_providers' => [
44+
[
45+
'id' => 1,
46+
'user_id' => 3,
47+
'provider' => 'gitlab',
48+
'identifier' => '123456',
49+
'last_login_at' => '2023-01-01 00:00:00'
50+
],
51+
[
52+
'id' => 2,
53+
'user_id' => 3,
54+
'provider' => 'github',
55+
'identifier' => '654321',
56+
'last_login_at' => '2023-01-02 00:00:00'
57+
],
58+
],
59+
]);
60+
}
61+
62+
/**
63+
* @test
64+
*/
65+
public function it_includes_login_provider_in_current_user_attributes()
66+
{
67+
// Log in as the user with OAuth providers
68+
$response = $this->send(
69+
$this->request('POST', '/login', [
70+
'json' => [
71+
'identification' => 'oauth_user',
72+
'password' => 'too-obscure',
73+
],
74+
])
75+
);
76+
77+
$this->assertEquals(200, $response->getStatusCode());
78+
79+
// Get the current user data
80+
$response = $this->send(
81+
$this->request('GET', '/api/users/3', ['cookiesFrom' => $response])
82+
);
83+
84+
$this->assertEquals(200, $response->getStatusCode());
85+
86+
$body = json_decode($response->getBody()->getContents(), true);
87+
88+
// Check that the loginProvider attribute is present and has the most recent provider
89+
$this->assertArrayHasKey('loginProvider', $body['data']['attributes']);
90+
$this->assertEquals('github', $body['data']['attributes']['loginProvider']);
91+
}
92+
93+
/**
94+
* @test
95+
*/
96+
public function it_returns_null_for_users_without_login_providers()
97+
{
98+
// Log in as a normal user without OAuth providers
99+
$response = $this->send(
100+
$this->request('POST', '/login', [
101+
'json' => [
102+
'identification' => 'normal',
103+
'password' => 'too-obscure',
104+
],
105+
])
106+
);
107+
108+
$this->assertEquals(200, $response->getStatusCode());
109+
110+
// Get the current user data
111+
$response = $this->send(
112+
$this->request('GET', '/api/users/2', ['cookiesFrom' => $response])
113+
);
114+
115+
$this->assertEquals(200, $response->getStatusCode());
116+
117+
$body = json_decode($response->getBody()->getContents(), true);
118+
119+
// Check that the loginProvider attribute is present but null
120+
$this->assertArrayHasKey('loginProvider', $body['data']['attributes']);
121+
$this->assertNull($body['data']['attributes']['loginProvider']);
122+
}
123+
124+
/**
125+
* @test
126+
*/
127+
public function it_uses_cached_provider_when_available()
128+
{
129+
// Log in as the user with OAuth providers
130+
$response = $this->send(
131+
$this->request('POST', '/login', [
132+
'json' => [
133+
'identification' => 'oauth_user',
134+
'password' => 'too-obscure',
135+
],
136+
])
137+
);
138+
139+
$this->assertEquals(200, $response->getStatusCode());
140+
141+
// Get the session ID from cookies
142+
$cookies = [];
143+
foreach ($response->getHeaders()['Set-Cookie'] as $cookie) {
144+
if (strpos($cookie, 'flarum_session=') === 0) {
145+
preg_match('/flarum_session=([^;]+)/', $cookie, $matches);
146+
$sessionId = $matches[1];
147+
break;
148+
}
149+
}
150+
151+
// Manually set a cached value
152+
$cache = $this->app()->getContainer()->make(Cache::class);
153+
$cache->forever(AbstractOAuthController::SESSION_OAUTH2PROVIDER.'_'.$sessionId, 'discord');
154+
155+
// Get the current user data
156+
$response = $this->send(
157+
$this->request('GET', '/api/users/3', ['cookiesFrom' => $response])
158+
);
159+
160+
$this->assertEquals(200, $response->getStatusCode());
161+
162+
$body = json_decode($response->getBody()->getContents(), true);
163+
164+
// Check that the loginProvider attribute uses the cached value
165+
$this->assertArrayHasKey('loginProvider', $body['data']['attributes']);
166+
$this->assertEquals('discord', $body['data']['attributes']['loginProvider']);
167+
}
168+
}

0 commit comments

Comments
 (0)