Testing OAuth2 Grant Service Implementation in RuoYi Vue Pro
This test suite validates the OAuth2 grant service implementation in the RuoYi Vue Pro system, covering different OAuth2 authorization flows and token management functionality. It ensures proper handling of various grant types including implicit, authorization code, password, and refresh token flows.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
yunaiv/ruoyi-vue-pro
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/oauth2/OAuth2GrantServiceImplTest.java
package cn.iocoder.yudao.module.system.service.oauth2;
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2CodeDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.List;
import static cn.hutool.core.util.RandomUtil.randomEle;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
import static java.util.Collections.emptyList;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when;
/**
* {@link OAuth2GrantServiceImpl} 的单元测试
*
* @author 芋道源码
*/
public class OAuth2GrantServiceImplTest extends BaseMockitoUnitTest {
@InjectMocks
private OAuth2GrantServiceImpl oauth2GrantService;
@Mock
private OAuth2TokenService oauth2TokenService;
@Mock
private OAuth2CodeService oauth2CodeService;
@Mock
private AdminAuthService adminAuthService;
@Test
public void testGrantImplicit() {
// 准备参数
Long userId = randomLongId();
Integer userType = randomEle(UserTypeEnum.values()).getValue();
String clientId = randomString();
List<String> scopes = Lists.newArrayList("read", "write");
// mock 方法
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
when(oauth2TokenService.createAccessToken(eq(userId), eq(userType),
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
// 调用,并断言
assertPojoEquals(accessTokenDO, oauth2GrantService.grantImplicit(
userId, userType, clientId, scopes));
}
@Test
public void testGrantAuthorizationCodeForCode() {
// 准备参数
Long userId = randomLongId();
Integer userType = randomEle(UserTypeEnum.values()).getValue();
String clientId = randomString();
List<String> scopes = Lists.newArrayList("read", "write");
String redirectUri = randomString();
String state = randomString();
// mock 方法
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class);
when(oauth2CodeService.createAuthorizationCode(eq(userId), eq(userType),
eq(clientId), eq(scopes), eq(redirectUri), eq(state))).thenReturn(codeDO);
// 调用,并断言
assertEquals(codeDO.getCode(), oauth2GrantService.grantAuthorizationCodeForCode(userId, userType,
clientId, scopes, redirectUri, state));
}
@Test
public void testGrantAuthorizationCodeForAccessToken() {
// 准备参数
String clientId = randomString();
String code = randomString();
List<String> scopes = Lists.newArrayList("read", "write");
String redirectUri = randomString();
String state = randomString();
// mock 方法(code)
OAuth2CodeDO codeDO = randomPojo(OAuth2CodeDO.class, o -> {
o.setClientId(clientId);
o.setRedirectUri(redirectUri);
o.setState(state);
o.setScopes(scopes);
});
when(oauth2CodeService.consumeAuthorizationCode(eq(code))).thenReturn(codeDO);
// mock 方法(创建令牌)
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
when(oauth2TokenService.createAccessToken(eq(codeDO.getUserId()), eq(codeDO.getUserType()),
eq(codeDO.getClientId()), eq(codeDO.getScopes()))).thenReturn(accessTokenDO);
// 调用,并断言
assertPojoEquals(accessTokenDO, oauth2GrantService.grantAuthorizationCodeForAccessToken(
clientId, code, redirectUri, state));
}
@Test
public void testGrantPassword() {
// 准备参数
String username = randomString();
String password = randomString();
String clientId = randomString();
List<String> scopes = Lists.newArrayList("read", "write");
// mock 方法(认证)
AdminUserDO user = randomPojo(AdminUserDO.class);
when(adminAuthService.authenticate(eq(username), eq(password))).thenReturn(user);
// mock 方法(访问令牌)
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
when(oauth2TokenService.createAccessToken(eq(user.getId()), eq(UserTypeEnum.ADMIN.getValue()),
eq(clientId), eq(scopes))).thenReturn(accessTokenDO);
// 调用,并断言
assertPojoEquals(accessTokenDO, oauth2GrantService.grantPassword(
username, password, clientId, scopes));
}
@Test
public void testGrantRefreshToken() {
// 准备参数
String refreshToken = randomString();
String clientId = randomString();
// mock 方法
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
when(oauth2TokenService.refreshAccessToken(eq(refreshToken), eq(clientId)))
.thenReturn(accessTokenDO);
// 调用,并断言
assertPojoEquals(accessTokenDO, oauth2GrantService.grantRefreshToken(
refreshToken, clientId));
}
@Test
public void testGrantClientCredentials() {
assertThrows(UnsupportedOperationException.class,
() -> oauth2GrantService.grantClientCredentials(randomString(), emptyList()),
"暂时不支持 client_credentials 授权模式");
}
@Test
public void testRevokeToken_clientIdError() {
// 准备参数
String clientId = randomString();
String accessToken = randomString();
// mock 方法
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class);
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
// 调用,并断言
assertFalse(oauth2GrantService.revokeToken(clientId, accessToken));
}
@Test
public void testRevokeToken_success() {
// 准备参数
String clientId = randomString();
String accessToken = randomString();
// mock 方法(访问令牌)
OAuth2AccessTokenDO accessTokenDO = randomPojo(OAuth2AccessTokenDO.class).setClientId(clientId);
when(oauth2TokenService.getAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
// mock 方法(移除)
when(oauth2TokenService.removeAccessToken(eq(accessToken))).thenReturn(accessTokenDO);
// 调用,并断言
assertTrue(oauth2GrantService.revokeToken(clientId, accessToken));
}
}