wordpress站群搭建6wordpress外部库的引入和测试
本次目标我们主要讲解引入wordpress
外部库并测试。
我们将一些外部库和工具包放入到pkg项目,方便其他项目引用。
1.安装go-wordpress库
进入到pkg
项目
go get github.com/robbiet480/go-wordpress
2.编写工具类
我们在添加station
的时候,在之前的代码中我们有几个todo,现在我们将这几个todo进行处理。
// todo 校验wordpress账号密码// todo 加密密码// todo 自动获取服务器ip
在pkg
包下创建 wordpressutil
目录,创建wordpressutil.go
文件,编写 创建客户端和测试账号密码方法。
wordpressutil.go
package wordpressutilimport ("context""fmt""github.com/robbiet480/go-wordpress"
)// 创建wordpress客户端
func Client(DomainName string, Username string, Password string) (client *wordpress.Client, err error) {Url := fmt.Sprintf("%s/wp-json", DomainName)tp := wordpress.BasicAuthTransport{Username: Username,Password: Password,}// create wp-api clientclient, err = wordpress.NewClient(Url, tp.Client())if err != nil {return nil, err}return client, nil
}// 测试账号是否正确
func Test(DomainName string, Username string, Password string) error {client, err := Client(DomainName, Username, Password)if err != nil {return err}_, r, err := client.Users.Me(context.Background(), nil)if err != nil {return err}if r.StatusCode != 200 {return fmt.Errorf("账号验证失败")}return nil
}
3.编写测试类
编写完工具方法后我们需要对接方法进行测试。
测试之前我们需要先准备到wordpress
的账号和密码。
在wordpressutil.go
同级目录创建 wordpressutil_test.go
文件。
测试类需要引入testing
包,测试方法以Test开头,参数为*testing.T
。下面是一个Test函数的典型定义
import "testing"
func Test_test(t *testing.T) {}
wordpressutil_test.go
package wordpressutilimport ("context""fmt""net/http""testing""github.com/robbiet480/go-wordpress"
)func getClient() (client *wordpress.Client, err error) {client, err = Client("https://xxx.com/wp-json/", "admin", "xxx")if err != nil {return nil, err}return client, nil
}// 测试Client函数
func Test_getClient(t *testing.T) {client, err := getClient()if err != nil {fmt.Println(err.Error())}media, resp, _ := client.Media.List(context.Background(), nil)if resp != nil && resp.StatusCode != http.StatusOK {t.Errorf("Expected 200 OK, got %v", resp.Status)}if len(media) < 1 {t.Fatalf("Should not return empty comments")}fmt.Println(media)
}// 测试Test函数
func Test12(t *testing.T) {err := Test("https://www.xxxxx.com/wp-json/", "gxx", "xxx")if err != nil {fmt.Println(err.Error())}
}// 测试Create_User函数
func Test_Create_User(t *testing.T) {client, err := getClient()if err != nil {fmt.Println(err.Error())}user, _, err := client.Users.Create(context.Background(), &wordpress.User{Username: "test", Email: "test@test.com"})if err != nil {fmt.Println(err.Error())}fmt.Println(user)
}
如果你使用vscode
在测试函数旁边有个测试按钮,直接进行测试。其他的ide也是类型的操作。
右键点击有更多操作下拉.
测试完成后们就可以在业务代码中使用了。使用时把 pkg/wordpressutil
包import
即可使用
4.编写其他工具类
有了上面的流程我们在引入下其他的工具类。由于涉及到密码所以我们存入数据库时需要进行加密,因此需要编写一个加密解密工具。
在pkg
包下创建 encryption
目录,创建encryption.go
文件
encryption.go
package encryptionimport ("crypto/aes""crypto/cipher""crypto/rand""crypto/sha256""encoding/base64""fmt""io"
)// AES加密函数
func AESEncrypt(plainText, key string) (string, error) {// 创建 AES 加密器block, err := aes.NewCipher(createHash(key))if err != nil {return "", err}// 使用 GCM 模式gcm, err := cipher.NewGCM(block)if err != nil {return "", err}// 创建 noncenonce := make([]byte, gcm.NonceSize())if _, err = io.ReadFull(rand.Reader, nonce); err != nil {return "", err}// 加密数据cipherText := gcm.Seal(nonce, nonce, []byte(plainText), nil)return base64.StdEncoding.EncodeToString(cipherText), nil
}// AES解密函数
func AESDecrypt(cipherText, key string) (string, error) {// 将密文解码data, err := base64.StdEncoding.DecodeString(cipherText)if err != nil {return "", err}// 创建 AES 解密器block, err := aes.NewCipher(createHash(key))if err != nil {return "", err}// 使用 GCM 模式gcm, err := cipher.NewGCM(block)if err != nil {return "", err}nonceSize := gcm.NonceSize()if len(data) < nonceSize {return "", fmt.Errorf("ciphertext too short")}// 解密nonce, cipherTextByte := data[:nonceSize], data[nonceSize:]plainText, err := gcm.Open(nil, nonce, cipherTextByte, nil)if err != nil {return "", err}return string(plainText), nil
}// 创建哈希函数
func createHash(key string) []byte {hash := sha256.New()hash.Write([]byte(key))return hash.Sum(nil)[:32] // AES-256 密钥需要32字节
}
encryption_test.go
package encryptionimport ("testing"
)func TestEncryption(t *testing.T) {res, err := AESEncrypt("hello", "12345678")if err != nil {t.Error(err)}t.Log(res)t.Log("---------------------")res, err = AESDecrypt(res, "12345678")if err != nil {t.Error(err)}t.Log(res)
}
同样的方式进行测试
iputil.go
package iputilimport ("errors""net""net/http""net/url""strings"
)func GetIP(r *http.Request) (string, error) {ip := r.Header.Get("X-Forwarded-For")for _, i := range strings.Split(ip, ",") {if net.ParseIP(i) != nil {return i, nil}}ip, _, err := net.SplitHostPort(r.RemoteAddr)if err != nil {return "", err}if net.ParseIP(ip) != nil {return ip, nil}return "", errors.New("no valid ip found")
}// 获取域名ip
func GetDomainIP(domain string) (string, error) {domain, err := extractDomain(domain)if err != nil {return "", err}ips, err := net.LookupIP(domain)if err != nil {return "", err}for _, ip := range ips {return ip.String(), err}return "", errors.New("no valid ip found")
}// 提取域名
func extractDomain(u string) (string, error) {if strings.Contains(u, "http") {parsedUrl, err := url.Parse(u)if err != nil {return "", err}return parsedUrl.Hostname(), nil}return u, nil
}
我们同样进行测试,这里就不直接复制出,大家可以自行测试练习。
5.业务代码调用
编写完工具类后,我们对之前业务代码中的todo 逻辑进行补全。
在addstationlogic.go
中我们在之前的todo处进行逻辑处理
addstationlogic.go
func (l *AddStationLogic) AddStation(in *types.StationInfo) (resp *types.StationInfoResp, err error) {//校验wordpress 账号密码err = wordpressutil.Test(in.DomainName, in.UserName, in.PassWord)if err != nil {return nil, err}// 加密密码pw, err := encryption.AESEncrypt(in.PassWord, l.svcCtx.Config.Secret.AESSecret)if err != nil {return nil, err}info := &station.StationInfo{Id: in.Id,DomainName: in.DomainName,DomainYear: in.DomainYear,GoogleWeight: in.GoogleWeight,Type: in.Type,Industry: in.Industry,UserName: in.UserName,PassWord: pw,ArticlesNum: in.ArticlesNum,Ip: in.Ip,}// 自动获取服务器ipif info.Ip == "" {ip, _ := iputil.GetDomainIP(info.DomainName)info.Ip = ip}// 后的代码省略了
}
这样我们完成了外部公共库的引入和使用。
完整代码查询 6wordpress外部库的引入和测试 代码分支 。
5.总结
引入公共库,工具类时,我们可以对其进行测试。测试使用testing,通过测试我们可以快速验证工具能力。测试做的完善可以大大减少我们bug量。