From 64f05627fbfd75a99f80b147e36aac627e61d313 Mon Sep 17 00:00:00 2001 From: FantasyRL <1845983502@qq.com> Date: Sat, 14 Dec 2024 15:22:28 +0800 Subject: [PATCH] add: url service test --- config/config.go | 28 ++-- .../version/service/get_all_setting_test.go | 97 ++++++++++++++ ...on_release_test.go => get_version_test.go} | 65 +++++++++ internal/version/service/login_test.go | 67 ++++++++++ internal/version/service/set_setting_test.go | 93 +++++++++++++ internal/version/service/upload_params.go | 5 +- .../version/service/upload_params_test.go | 95 ++++++++++++++ .../version/service/upload_version_test.go | 124 ++++++++++++++++++ pkg/upyun/{url.go => version.go} | 18 +-- pkg/utils/check_pwd.go | 2 +- 10 files changed, 567 insertions(+), 27 deletions(-) create mode 100644 internal/version/service/get_all_setting_test.go rename internal/version/service/{get_version_release_test.go => get_version_test.go} (58%) create mode 100644 internal/version/service/login_test.go create mode 100644 internal/version/service/set_setting_test.go create mode 100644 internal/version/service/upload_params_test.go create mode 100644 internal/version/service/upload_version_test.go rename pkg/upyun/{url.go => version.go} (84%) diff --git a/config/config.go b/config/config.go index 6b7590fc..0a507fa6 100644 --- a/config/config.go +++ b/config/config.go @@ -28,19 +28,19 @@ import ( ) var ( - Server *server - Mysql *mySQL - Snowflake *snowflake - Service *service - Jaeger *jaeger - Etcd *etcd - Redis *redis - DefaultUser *defaultUser - Elasticsearch *elasticsearch - Kafka *kafka - UpYun *upyun - UrlService *url - runtimeViper = viper.New() + Server *server + Mysql *mySQL + Snowflake *snowflake + Service *service + Jaeger *jaeger + Etcd *etcd + Redis *redis + DefaultUser *defaultUser + Elasticsearch *elasticsearch + Kafka *kafka + UpYun *upyun + VersionUploadService *url + runtimeViper = viper.New() ) func Init(service string) { @@ -89,7 +89,7 @@ func configMapping(srv string) { Elasticsearch = &c.Elasticsearch Kafka = &c.Kafka DefaultUser = &c.DefaultUser - UrlService = &c.Url + VersionUploadService = &c.Url upy, ok := c.UpYuns[srv] if ok { UpYun = &upy diff --git a/internal/version/service/get_all_setting_test.go b/internal/version/service/get_all_setting_test.go new file mode 100644 index 00000000..b8c7a2a7 --- /dev/null +++ b/internal/version/service/get_all_setting_test.go @@ -0,0 +1,97 @@ +package service + +import ( + "fmt" + "github.com/west2-online/fzuhelper-server/pkg/upyun" + "testing" + + "github.com/bytedance/mockey" + "github.com/stretchr/testify/assert" +) + +func TestGetAllCloudSetting(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockSettingJson *[]byte // mock返回的设置 JSON 数据 + mockError error // mock返回的错误 + expectedResult *[]byte // 期望返回的结果 + expectingError bool // 是否期望抛出错误 + expectedErrorInfo string // 期望的错误信息 + mockCommentedJson string // 模拟带注释的 JSON 数据 + mockCommentedError error // 模拟去掉注释过程的错误 + } + + mockResult := []byte(`{"key": "value"}`) + // 测试用例 + testCases := []testCase{ + { + name: "SuccessCase", + mockSettingJson: &mockResult, + mockError: nil, + expectedResult: &mockResult, + expectingError: false, + expectedErrorInfo: "", + mockCommentedJson: `{"key": "value"}`, + mockCommentedError: nil, + }, + { + name: "FileNotFound", + mockSettingJson: nil, + mockError: fmt.Errorf("file not found"), + expectedResult: nil, + expectingError: true, + expectedErrorInfo: "VersionService.GetAllCloudSetting error:file not found", + mockCommentedJson: "", + mockCommentedError: nil, + }, + { + name: "RemoveCommentsError", + mockSettingJson: &mockResult, + mockError: nil, + expectedResult: nil, + expectingError: true, + expectedErrorInfo: "VersionService.GetAllCloudSetting error:invalid JSON format", + mockCommentedJson: "", + mockCommentedError: fmt.Errorf("invalid JSON format"), + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock upyun.URlGetFile 方法 + mockey.Mock(upyun.URlGetFile).To(func(filename string) (*[]byte, error) { + return tc.mockSettingJson, tc.mockError + }).Build() + mockey.Mock(upyun.JoinFileName).To(func(filename string) string { + return filename + }).Build() + + // Mock getJSONWithoutComments 方法 + mockey.Mock(getJSONWithoutComments).To(func(json string) (string, error) { + if tc.mockCommentedError != nil { + return "", tc.mockCommentedError + } + return tc.mockCommentedJson, nil + }).Build() + + // 初始化UrlService实例 + versionService := &VersionService{} + + // 调用方法 + result, err := versionService.GetAllCloudSetting() + + if tc.expectingError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.EqualError(t, err, tc.expectedErrorInfo) + assert.Equal(t, tc.expectedResult, result) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + assert.Equal(t, tc.expectedResult, result) + } + }) + } +} diff --git a/internal/version/service/get_version_release_test.go b/internal/version/service/get_version_test.go similarity index 58% rename from internal/version/service/get_version_release_test.go rename to internal/version/service/get_version_test.go index 7ad56c29..47bc6fd8 100644 --- a/internal/version/service/get_version_release_test.go +++ b/internal/version/service/get_version_test.go @@ -92,3 +92,68 @@ func TestGetReleaseVersion(t *testing.T) { }) } } + +func TestGetBetaVersion(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockJsonBytes *[]byte // mock返回的JSON数据 + mockError error // mock返回的错误 + expectedResult *pack.Version // 期望返回的结果 + expectingError bool // 是否期望抛出错误 + expectedErrorInfo string // 期望的错误信息 + } + + // 模拟数据 + mockVersion := &pack.Version{Url: "http://example.com/beta.apk", Version: "1.0.0"} + mockVersionBytes, _ := json.Marshal(mockVersion) + + testCases := []testCase{ + { + name: "SuccessCase", + mockJsonBytes: &mockVersionBytes, + mockError: nil, + expectedResult: mockVersion, + expectingError: false, + expectedErrorInfo: "", + }, + { + name: "FileNotFound", + mockJsonBytes: nil, + mockError: fmt.Errorf("file not found"), + expectedResult: nil, + expectingError: true, + expectedErrorInfo: "VersionService.GetBetaVersion error:file not found", + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock upyun.URlGetFile 方法 + mockey.Mock(upyun.URlGetFile).To(func(filename string) (*[]byte, error) { + return tc.mockJsonBytes, tc.mockError + }).Build() + mockey.Mock(upyun.JoinFileName).To(func(filename string) string { + return filename + }).Build() + + // 初始化 VersionService 实例 + urlService := &VersionService{} + + // 调用方法 + result, err := urlService.GetBetaVersion() + + if tc.expectingError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.EqualError(t, err, tc.expectedErrorInfo) + assert.Nil(t, result) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + assert.Equal(t, tc.expectedResult, result) + } + }) + } +} diff --git a/internal/version/service/login_test.go b/internal/version/service/login_test.go new file mode 100644 index 00000000..ea5ff141 --- /dev/null +++ b/internal/version/service/login_test.go @@ -0,0 +1,67 @@ +package service + +import ( + "testing" + + "github.com/bytedance/mockey" + "github.com/stretchr/testify/assert" + + "github.com/west2-online/fzuhelper-server/kitex_gen/version" + "github.com/west2-online/fzuhelper-server/pkg/utils" +) + +func TestLogin(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockCheckPwd bool // 模拟 CheckPwd 的返回值 + request *version.LoginRequest // 输入的登录请求 + expectedError bool // 是否期望抛出错误 + expectedErrorMsg string // 期望的错误类型或信息 + } + + testCases := []testCase{ + { + name: "ValidPassword", + mockCheckPwd: true, + request: &version.LoginRequest{ + Password: "validpassword", + }, + expectedError: false, + }, + { + name: "InvalidPassword", + mockCheckPwd: false, + request: &version.LoginRequest{ + Password: "invalidpassword", + }, + expectedError: true, + expectedErrorMsg: "[401] authorization failed", + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock utils.CheckPwd 方法 + mockey.Mock(utils.CheckPwd).To(func(password string) bool { + return tc.mockCheckPwd + }).Build() + + // 初始化 UrlService 实例 + versionService := &VersionService{} + + // 调用方法 + err := versionService.Login(tc.request) + + if tc.expectedError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.Contains(t, err.Error(), tc.expectedErrorMsg) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + } + }) + } +} diff --git a/internal/version/service/set_setting_test.go b/internal/version/service/set_setting_test.go new file mode 100644 index 00000000..6b416f76 --- /dev/null +++ b/internal/version/service/set_setting_test.go @@ -0,0 +1,93 @@ +package service + +import ( + "fmt" + "testing" + + "github.com/bytedance/mockey" + "github.com/stretchr/testify/assert" + + "github.com/west2-online/fzuhelper-server/kitex_gen/version" + "github.com/west2-online/fzuhelper-server/pkg/upyun" + "github.com/west2-online/fzuhelper-server/pkg/utils" +) + +func TestSetSetting(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockCheckPwd bool // 模拟 CheckPwd 的返回值 + mockUploadError error // 模拟 URlUploadFile 的错误 + request *version.SetCloudRequest // 输入的请求 + expectedError bool // 是否期望抛出错误 + expectedErrorInfo string // 期望的错误信息 + } + + testCases := []testCase{ + { + name: "ValidPasswordAndSuccessfulUpload", + mockCheckPwd: true, + mockUploadError: nil, + request: &version.SetCloudRequest{ + Password: "validpassword", + Setting: "{\"key\": \"value\"}", + }, + expectedError: false, + }, + { + name: "InvalidPassword", + mockCheckPwd: false, + mockUploadError: nil, + request: &version.SetCloudRequest{ + Password: "invalidpassword", + Setting: "{\"key\": \"value\"}", + }, + expectedError: true, + expectedErrorInfo: "[401] authorization failed", // 假设 buildAuthFailedError 返回这个错误信息 + }, + { + name: "ValidPasswordButUploadFails", + mockCheckPwd: true, + mockUploadError: fmt.Errorf("upload failed"), + request: &version.SetCloudRequest{ + Password: "validpassword", + Setting: "{\"key\": \"value\"}", + }, + expectedError: true, + expectedErrorInfo: "upload failed", + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock utils.CheckPwd 方法 + mockey.Mock(utils.CheckPwd).To(func(password string) bool { + return tc.mockCheckPwd + }).Build() + + // Mock upyun.URlUploadFile 方法 + mockey.Mock(upyun.URlUploadFile).To(func(data []byte, filename string) error { + return tc.mockUploadError + }).Build() + mockey.Mock(upyun.JoinFileName).To(func(filename string) string { + return filename + }).Build() + + // 初始化 UrlService 实例 + versionService := &VersionService{} + + // 调用方法 + err := versionService.SetSetting(tc.request) + + if tc.expectedError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.Contains(t, err.Error(), tc.expectedErrorInfo) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + } + }) + } +} diff --git a/internal/version/service/upload_params.go b/internal/version/service/upload_params.go index 780fe89a..a3be3d03 100644 --- a/internal/version/service/upload_params.go +++ b/internal/version/service/upload_params.go @@ -17,7 +17,6 @@ limitations under the License. package service import ( - "github.com/west2-online/fzuhelper-server/config" "github.com/west2-online/fzuhelper-server/kitex_gen/version" "github.com/west2-online/fzuhelper-server/pkg/upyun" "github.com/west2-online/fzuhelper-server/pkg/utils" @@ -28,7 +27,7 @@ func (s *VersionService) UploadParams(req *version.UploadParamsRequest) (string, if !utils.CheckPwd(req.Password) { return "", "", buildAuthFailedError() } - policy := upyun.GetPolicy(config.UrlService.Bucket, config.UrlService.Path, int(config.UrlService.TokenTimeout)) - authorization := upyun.SignStr(config.UrlService.Operator, config.UrlService.Pass, config.UrlService.Bucket, policy) + policy := upyun.GetPolicy() + authorization := upyun.SignStr(policy) return policy, authorization, nil } diff --git a/internal/version/service/upload_params_test.go b/internal/version/service/upload_params_test.go new file mode 100644 index 00000000..e2a11225 --- /dev/null +++ b/internal/version/service/upload_params_test.go @@ -0,0 +1,95 @@ +package service + +import ( + "testing" + + "github.com/bytedance/mockey" + "github.com/stretchr/testify/assert" + + "github.com/west2-online/fzuhelper-server/kitex_gen/version" + "github.com/west2-online/fzuhelper-server/pkg/upyun" + "github.com/west2-online/fzuhelper-server/pkg/utils" +) + +func TestUploadParams(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockCheckPwd bool // 模拟 CheckPwd 的返回值 + mockPolicy string // 模拟 GetPolicy 的返回值 + mockAuthorization string // 模拟 SignStr 的返回值 + request *version.UploadParamsRequest // 请求参数 + expectedPolicy string // 期望的 policy 返回值 + expectedAuthorization string // 期望的 authorization 返回值 + expectedError bool // 是否期望抛出错误 + expectedErrorInfo string // 期望的错误信息 + } + + // 测试用例 + testCases := []testCase{ + { + name: "ValidPassword", + mockCheckPwd: true, + mockPolicy: "mockPolicy", + mockAuthorization: "mockAuthorization", + request: &version.UploadParamsRequest{ + Password: "validpassword", + }, + expectedPolicy: "mockPolicy", + expectedAuthorization: "mockAuthorization", + expectedError: false, + }, + { + name: "InvalidPassword", + mockCheckPwd: false, + mockPolicy: "", + mockAuthorization: "", + request: &version.UploadParamsRequest{ + Password: "invalidpassword", + }, + expectedPolicy: "", + expectedAuthorization: "", + expectedError: true, + expectedErrorInfo: "[401] authorization failed", // 假设 buildAuthFailedError 返回这个错误信息 + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock utils.CheckPwd 方法 + mockey.Mock(utils.CheckPwd).To(func(password string) bool { + return tc.mockCheckPwd + }).Build() + + // Mock upyun.GetPolicy 方法 + mockey.Mock(upyun.GetPolicy).To(func() string { + return tc.mockPolicy + }).Build() + + // Mock upyun.SignStr 方法 + mockey.Mock(upyun.SignStr).To(func(policy string) string { + return tc.mockAuthorization + }).Build() + + // 初始化 UrlService 实例 + versionService := &VersionService{} + + // 调用方法 + policy, authorization, err := versionService.UploadParams(tc.request) + + if tc.expectedError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.Contains(t, err.Error(), tc.expectedErrorInfo) + assert.Equal(t, tc.expectedPolicy, policy) + assert.Equal(t, tc.expectedAuthorization, authorization) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + assert.Equal(t, tc.expectedPolicy, policy) + assert.Equal(t, tc.expectedAuthorization, authorization) + } + }) + } +} diff --git a/internal/version/service/upload_version_test.go b/internal/version/service/upload_version_test.go new file mode 100644 index 00000000..923b9465 --- /dev/null +++ b/internal/version/service/upload_version_test.go @@ -0,0 +1,124 @@ +package service + +import ( + "testing" + + "github.com/bytedance/mockey" + "github.com/stretchr/testify/assert" + + "github.com/west2-online/fzuhelper-server/kitex_gen/version" + "github.com/west2-online/fzuhelper-server/pkg/upyun" + "github.com/west2-online/fzuhelper-server/pkg/utils" +) + +func TestUploadVersion(t *testing.T) { + type testCase struct { + name string // 测试用例名称 + mockCheckPwd bool // 模拟 CheckPwd 的返回值 + mockUploadError error // 模拟 URlUploadFile 的错误 + mockMarshalError error // 模拟 JSON Marshal 的错误 + request *version.UploadRequest // 请求参数 + expectedError bool // 是否期望抛出错误 + expectedErrorInfo string // 期望的错误信息 + } + + // 测试用例 + testCases := []testCase{ + { + name: "ValidPasswordAndUploadRelease", + mockCheckPwd: true, + mockUploadError: nil, + mockMarshalError: nil, + request: &version.UploadRequest{ + Password: "validpassword", + Version: "1.0.0", + Code: "633001", + Url: "http://example.com/release.apk", + Feature: "New features", + Type: apkTypeRelease, + }, + expectedError: false, + }, + { + name: "ValidPasswordAndUploadBeta", + mockCheckPwd: true, + mockUploadError: nil, + mockMarshalError: nil, + request: &version.UploadRequest{ + Password: "validpassword", + Version: "1.0.1-beta", + Code: "633001", + Url: "http://example.com/beta.apk", + Feature: "Beta features", + Type: apkTypeBeta, + }, + expectedError: false, + }, + { + name: "InvalidPassword", + mockCheckPwd: false, + mockUploadError: nil, + mockMarshalError: nil, + request: &version.UploadRequest{ + Password: "invalidpassword", + Version: "1.0.0", + Code: "633001", + Url: "http://example.com/release.apk", + Feature: "New features", + Type: apkTypeRelease, + }, + expectedError: true, + expectedErrorInfo: "[401] authorization failed", + }, + { + name: "InvalidApkType", + mockCheckPwd: true, + mockUploadError: nil, + mockMarshalError: nil, + request: &version.UploadRequest{ + Password: "validpassword", + Version: "1.0.0", + Code: "633001", + Url: "http://example.com/release.apk", + Feature: "New features", + Type: "invalidType", + }, + expectedError: true, + expectedErrorInfo: "parameter error", + }, + } + + defer mockey.UnPatchAll() // 清理所有mock + + for _, tc := range testCases { + mockey.PatchConvey(tc.name, t, func() { + // Mock utils.CheckPwd 方法 + mockey.Mock(utils.CheckPwd).To(func(password string) bool { + return tc.mockCheckPwd + }).Build() + + // Mock upyun.URlUploadFile 方法 + mockey.Mock(upyun.URlUploadFile).To(func(data []byte, filename string) error { + return tc.mockUploadError + }).Build() + mockey.Mock(upyun.JoinFileName).To(func(filename string) string { + return filename + }).Build() + + // 初始化 UrlService 实例 + versionService := &VersionService{} + + // 调用方法 + err := versionService.UploadVersion(tc.request) + + if tc.expectedError { + // 如果期望抛错,检查错误信息 + assert.NotNil(t, err) + assert.Contains(t, err.Error(), tc.expectedErrorInfo) + } else { + // 如果不期望抛错,验证结果 + assert.Nil(t, err) + } + }) + } +} diff --git a/pkg/upyun/url.go b/pkg/upyun/version.go similarity index 84% rename from pkg/upyun/url.go rename to pkg/upyun/version.go index a2644bdb..4e91f51f 100644 --- a/pkg/upyun/url.go +++ b/pkg/upyun/version.go @@ -39,18 +39,18 @@ func gmtDate() string { } // SignStr generates the signature string for authentication. -func SignStr(opename, opepass, bucket, policy string) string { +func SignStr(policy string) string { // Generate MD5 hash of the password md5Hasher := md5.New() - md5Hasher.Write([]byte(opepass)) + md5Hasher.Write([]byte(config.VersionUploadService.Pass)) key := fmt.Sprintf("%x", md5Hasher.Sum(nil)) gmtdate := gmtDate() var msg string if policy == "" { - msg = "POST" + "&/" + bucket + "&" + gmtdate + msg = "POST" + "&/" + config.VersionUploadService.Bucket + "&" + gmtdate } else { - msg = "POST" + "&/" + bucket + "&" + gmtdate + "&" + policy + msg = "POST" + "&/" + config.VersionUploadService.Bucket + "&" + gmtdate + "&" + policy } // Generate HMAC-SHA1 hash @@ -58,17 +58,17 @@ func SignStr(opename, opepass, bucket, policy string) string { hmacHasher.Write([]byte(msg)) signature := base64.StdEncoding.EncodeToString(hmacHasher.Sum(nil)) - return "UPYUN " + opename + ":" + signature + return "UPYUN " + config.VersionUploadService.Operator + ":" + signature } // GetPolicy generates the policy string for requests. -func GetPolicy(bucket, savepath string, timeout int) string { +func GetPolicy() string { gmtdate := gmtDate() - expiration := time.Now().Unix() + int64(timeout) + expiration := time.Now().Unix() + config.VersionUploadService.TokenTimeout // expiration := timeout policy := map[string]interface{}{ - "bucket": bucket, - "save-key": savepath, + "bucket": config.VersionUploadService.Bucket, + "save-key": config.VersionUploadService.Path, "expiration": expiration, "date": gmtdate, } diff --git a/pkg/utils/check_pwd.go b/pkg/utils/check_pwd.go index 0ba87c33..c3b18299 100644 --- a/pkg/utils/check_pwd.go +++ b/pkg/utils/check_pwd.go @@ -23,5 +23,5 @@ import ( ) func CheckPwd(pwd string) bool { - return strings.Compare(pwd, config.UrlService.Password) == 0 + return strings.Compare(pwd, config.VersionUploadService.Password) == 0 }