su2a / backend /internal /handler /auth_dingtalk_client_test.go
cjovs's picture
PG local + bucket backup/restore, DB: su2adb
126ef31 verified
Raw
History Blame Contribute Delete
5.13 kB
package handler
import (
"context"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestDingTalkClient_ExchangeCodeForUserToken_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "POST", r.Method)
require.Equal(t, "/v1.0/oauth2/userAccessToken", r.URL.Path)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"accessToken":"USER_TOKEN_X","expireIn":7200,"refreshToken":"R","corpId":"dingABC"}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{
ClientID: "k", ClientSecret: "s",
TokenURL: server.URL + "/v1.0/oauth2/userAccessToken",
},
httpClient: server.Client(),
}
resp, err := cli.ExchangeCodeForUserToken(context.Background(), "AUTH_CODE")
require.NoError(t, err)
require.Equal(t, "USER_TOKEN_X", resp.AccessToken)
require.Equal(t, "dingABC", resp.CorpID)
}
func TestDingTalkClient_GetUnionIdByUserToken_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "USER_TOKEN_X", r.Header.Get("x-acs-dingtalk-access-token"))
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"nick":"张三","unionId":"UID_AAA","openId":"OPEN","avatarUrl":"http://x"}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{UserInfoURL: server.URL + "/v1.0/contact/users/me"},
httpClient: server.Client(),
}
unionID, nick, err := cli.GetUnionIdByUserToken(context.Background(), "USER_TOKEN_X")
require.NoError(t, err)
require.Equal(t, "UID_AAA", unionID)
require.Equal(t, "张三", nick)
}
func TestDingTalkClient_GetAppToken_Cached(t *testing.T) {
callCount := 0
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
callCount++
_, _ = w.Write([]byte(`{"accessToken":"APP_TKN","expireIn":7200}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{ClientID: "k", ClientSecret: "s", TokenURL: server.URL + "/gettoken"},
httpClient: server.Client(),
}
t1, err := cli.GetAppToken(context.Background())
require.NoError(t, err)
t2, err := cli.GetAppToken(context.Background())
require.NoError(t, err)
require.Equal(t, t1, t2)
require.Equal(t, 1, callCount, "second call should hit cache")
}
func TestDingTalkClient_GetUserIdByUnionId_60011(t *testing.T) {
appTokenServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write([]byte(`{"accessToken":"APP_TKN","expireIn":7200}`))
}))
defer appTokenServer.Close()
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"errcode":60011,"errmsg":"not in directory"}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{TokenURL: appTokenServer.URL + "/gettoken"},
httpClient: server.Client(),
}
cli.appToken = "APP_TKN"
cli.appTokenExp = time.Now().Add(time.Hour)
cli.cfg.UserInfoURL = server.URL + "/v1.0/contact/users/byUnionId"
_, err := cli.GetUserIdByUnionId(context.Background(), "UID_AAA")
require.Error(t, err)
apiErr, ok := err.(*DingTalkAPIError)
require.True(t, ok)
require.Equal(t, "60011", apiErr.Code)
}
// TestDingTalkClient_GetDeptInfo_Success 验证 GetDeptInfo 正常情况返回部门信息。
func TestDingTalkClient_GetDeptInfo_Success(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"errcode":0,"errmsg":"ok","result":{"dept_id":42,"name":"AI数据","parent_id":1}}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{
UserInfoURL: server.URL + "/stub", // 不含 /contact/users/me,走 test stub 路径
},
httpClient: server.Client(),
}
cli.appToken = "APP_TKN"
cli.appTokenExp = time.Now().Add(time.Hour)
info, err := cli.GetDeptInfo(context.Background(), 42)
require.NoError(t, err)
require.Equal(t, int64(42), info.DeptID)
require.Equal(t, "AI数据", info.Name)
require.Equal(t, int64(1), info.ParentID)
}
// TestDingTalkClient_GetDeptInfo_ErrCode60003 验证 errcode=60003(部门不存在)时返回错误。
func TestDingTalkClient_GetDeptInfo_ErrCode60003(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"errcode":60003,"errmsg":"dept not found"}`))
}))
defer server.Close()
cli := &DingTalkClient{
cfg: dingTalkClientConfig{UserInfoURL: server.URL + "/stub"},
httpClient: server.Client(),
}
cli.appToken = "APP_TKN"
cli.appTokenExp = time.Now().Add(time.Hour)
_, err := cli.GetDeptInfo(context.Background(), 999)
require.Error(t, err)
apiErr, ok := err.(*DingTalkAPIError)
require.True(t, ok)
require.Equal(t, "60003", apiErr.Code)
}