| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- 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)
- }
|