|
@@ -0,0 +1,405 @@
|
|
|
|
|
+package main
|
|
|
|
|
+
|
|
|
|
|
+import (
|
|
|
|
|
+ "encoding/json"
|
|
|
|
|
+ "fmt"
|
|
|
|
|
+ "github.com/spf13/cast"
|
|
|
|
|
+ "io"
|
|
|
|
|
+ "net"
|
|
|
|
|
+ "net/http"
|
|
|
|
|
+ "net/http/cookiejar"
|
|
|
|
|
+ "os"
|
|
|
|
|
+ "pmail/db"
|
|
|
|
|
+ "pmail/dto/response"
|
|
|
|
|
+ "pmail/models"
|
|
|
|
|
+ "pmail/services/setup"
|
|
|
|
|
+ "pmail/signal"
|
|
|
|
|
+ "strconv"
|
|
|
|
|
+ "strings"
|
|
|
|
|
+ "testing"
|
|
|
|
|
+ "time"
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+var httpClient *http.Client
|
|
|
|
|
+
|
|
|
|
|
+const TestPort = 17888
|
|
|
|
|
+
|
|
|
|
|
+var TestHost string = "http://127.0.0.1:" + cast.ToString(TestPort)
|
|
|
|
|
+
|
|
|
|
|
+func TestMain(m *testing.M) {
|
|
|
|
|
+ cookeieJar, err := cookiejar.New(nil)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ panic(err)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ httpClient = &http.Client{Jar: cookeieJar, Timeout: 5 * time.Second}
|
|
|
|
|
+ os.Remove("config/config.json")
|
|
|
|
|
+ os.Remove("config/pmail_temp.db")
|
|
|
|
|
+ go func() {
|
|
|
|
|
+ main()
|
|
|
|
|
+ }()
|
|
|
|
|
+ time.Sleep(3 * time.Second)
|
|
|
|
|
+
|
|
|
|
|
+ m.Run()
|
|
|
|
|
+
|
|
|
|
|
+ signal.StopChan <- true
|
|
|
|
|
+ time.Sleep(3 * time.Second)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func TestMaster(t *testing.T) {
|
|
|
|
|
+ t.Run("TestPort", testPort)
|
|
|
|
|
+ t.Run("testDataBaseSet", testDataBaseSet)
|
|
|
|
|
+ t.Run("testPwdSet", testPwdSet)
|
|
|
|
|
+ t.Run("testDomainSet", testDomainSet)
|
|
|
|
|
+ t.Run("testDNSSet", testDNSSet)
|
|
|
|
|
+ cfg, err := setup.ReadConfig()
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatal(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ cfg.HttpsEnabled = 2
|
|
|
|
|
+ cfg.HttpPort = TestPort
|
|
|
|
|
+ err = setup.WriteConfig(cfg)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Fatal(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ t.Run("testSSLSet", testSSLSet)
|
|
|
|
|
+ time.Sleep(3 * time.Second)
|
|
|
|
|
+ t.Run("testLogin", testLogin)
|
|
|
|
|
+ t.Run("testSendEmail", testSendEmail)
|
|
|
|
|
+ time.Sleep(3 * time.Second)
|
|
|
|
|
+ t.Run("testEmailList", testEmailList)
|
|
|
|
|
+ t.Run("testDelEmail", testDelEmail)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testPort(t *testing.T) {
|
|
|
|
|
+ if !portCheck(TestPort) {
|
|
|
|
|
+ t.Error("port check failed")
|
|
|
|
|
+ }
|
|
|
|
|
+ t.Log("port check passed")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testDataBaseSet(t *testing.T) {
|
|
|
|
|
+
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err := http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"database\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Database Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader(`
|
|
|
|
|
+{"action":"set","step":"database","db_type":"sqlite","db_dsn":"./config/pmail_temp.db"}
|
|
|
|
|
+`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Database Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"database\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Database Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ dt := data.Data.(map[string]interface{})
|
|
|
|
|
+ if cast.ToString(dt["db_dsn"]) != "./config/pmail_temp.db" {
|
|
|
|
|
+ t.Error("Check Database Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ t.Log("Database Config Api Success!")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testPwdSet(t *testing.T) {
|
|
|
|
|
+
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err := http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"password\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Password Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader(`
|
|
|
|
|
+{"action":"set","step":"password","account":"testCase","password":"testCase"}
|
|
|
|
|
+`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Set Password Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"password\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Password Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if cast.ToString(data.Data) != "testCase" {
|
|
|
|
|
+ t.Error("Check Password Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ t.Log("Password Config Api Success!")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testDomainSet(t *testing.T) {
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err := http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"domain\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader(`
|
|
|
|
|
+{"action":"set","step":"domain","smtp_domain":"test.domain","web_domain":"mail.test.domain"}
|
|
|
|
|
+`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Set domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"domain\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Password Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ dt := data.Data.(map[string]interface{})
|
|
|
|
|
+
|
|
|
|
|
+ if cast.ToString(dt["smtp_domain"]) != "test.domain" {
|
|
|
|
|
+ t.Error("Check domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ if cast.ToString(dt["web_domain"]) != "mail.test.domain" {
|
|
|
|
|
+ t.Error("Check domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ t.Log("domain Config Api Success!")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testDNSSet(t *testing.T) {
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err := http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"dns\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testSSLSet(t *testing.T) {
|
|
|
|
|
+ // 获取配置
|
|
|
|
|
+ ret, err := http.Post(TestHost+"/api/setup", "application/json", strings.NewReader("{\"action\":\"get\",\"step\":\"ssl\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置配置
|
|
|
|
|
+ ret, err = http.Post(TestHost+"/api/setup", "application/json", strings.NewReader(`
|
|
|
|
|
+{"action":"set","step":"ssl","ssl_type":"1","key_path":"./config/ssl/private.key","crt_path":"./config/ssl/public.crt"}
|
|
|
|
|
+`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Set domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ t.Log("domain Config Api Success!")
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testLogin(t *testing.T) {
|
|
|
|
|
+ ret, err := httpClient.Post(TestHost+"/api/login", "application/json", strings.NewReader("{\"account\":\"testCase\",\"password\":\"testCase\"}"))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get domain Config Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testSendEmail(t *testing.T) {
|
|
|
|
|
+ ret, err := httpClient.Post(TestHost+"/api/email/send", "application/json", strings.NewReader(`
|
|
|
|
|
+ {
|
|
|
|
|
+ "from": {
|
|
|
|
|
+ "name": "i",
|
|
|
|
|
+ "email": "i@test.domain"
|
|
|
|
|
+ },
|
|
|
|
|
+ "to": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "name": "y",
|
|
|
|
|
+ "email": "y@test.domain"
|
|
|
|
|
+ }
|
|
|
|
|
+ ],
|
|
|
|
|
+ "cc": [
|
|
|
|
|
+
|
|
|
|
|
+ ],
|
|
|
|
|
+ "subject": "Title",
|
|
|
|
|
+ "text": "text",
|
|
|
|
|
+ "html": "<div>text</div>"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Send Email Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testEmailList(t *testing.T) {
|
|
|
|
|
+ ret, err := httpClient.Post(TestHost+"/api/email/list", "application/json", strings.NewReader(`{}`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Email List Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ dt := data.Data.(map[string]interface{})
|
|
|
|
|
+ if len(dt["list"].([]interface{})) == 0 {
|
|
|
|
|
+ t.Error("Email List Is Empty!")
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func testDelEmail(t *testing.T) {
|
|
|
|
|
+ ret, err := httpClient.Post(TestHost+"/api/email/list", "application/json", strings.NewReader(`{}`))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err := readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Get Email List Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ dt := data.Data.(map[string]interface{})
|
|
|
|
|
+ if len(dt["list"].([]interface{})) == 0 {
|
|
|
|
|
+ t.Error("Email List Is Empty!")
|
|
|
|
|
+ }
|
|
|
|
|
+ lst := dt["list"].([]interface{})
|
|
|
|
|
+ item := lst[0].(map[string]interface{})
|
|
|
|
|
+ id := cast.ToInt(item["id"])
|
|
|
|
|
+
|
|
|
|
|
+ ret, err = httpClient.Post(TestHost+"/api/email/del", "application/json", strings.NewReader(fmt.Sprintf(`{
|
|
|
|
|
+ "ids":[%d]
|
|
|
|
|
+}`, id)))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ data, err = readResponse(ret.Body)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ t.Error(err)
|
|
|
|
|
+ }
|
|
|
|
|
+ if data.ErrorNo != 0 {
|
|
|
|
|
+ t.Error("Email Delete Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+ var mail models.Email
|
|
|
|
|
+ db.Instance.Where("id = ?", id).Get(&mail)
|
|
|
|
|
+ if mail.Status != 3 {
|
|
|
|
|
+ t.Error("Email Delete Api Error!")
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// portCheck 检查端口是占用
|
|
|
|
|
+func portCheck(port int) bool {
|
|
|
|
|
+ l, err := net.Listen("tcp", fmt.Sprintf(":%s", strconv.Itoa(port)))
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+ defer l.Close()
|
|
|
|
|
+ return false
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func readResponse(r io.Reader) (*response.Response, error) {
|
|
|
|
|
+ data, err := io.ReadAll(r)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ ret := &response.Response{}
|
|
|
|
|
+ err = json.Unmarshal(data, ret)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return nil, err
|
|
|
|
|
+ }
|
|
|
|
|
+ return ret, nil
|
|
|
|
|
+}
|