package com.iailab.module.system.service.oauth2; import com.iailab.framework.common.enums.UserTypeEnum; import com.iailab.framework.test.core.ut.BaseMockitoUnitTest; import com.iailab.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; import com.iailab.module.system.dal.dataobject.oauth2.OAuth2CodeDO; import com.iailab.module.system.dal.dataobject.user.AdminUserDO; import com.iailab.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 com.iailab.framework.test.core.util.AssertUtils.assertPojoEquals; import static com.iailab.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 iailab */ 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 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 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 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 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)); } }