Skip to content

Commit f30caf9

Browse files
committed
test code 1 and fix some logic
1 parent 560f48a commit f30caf9

File tree

5 files changed

+209
-5
lines changed

5 files changed

+209
-5
lines changed

services/imap/cron.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func FetchAllUnReadMails() (err error) {
2626
}
2727
}
2828

29-
if !mailReadQueue.IsEmpty() {
29+
if !testMode && !mailReadQueue.IsEmpty() {
3030
return
3131
}
3232

services/imap/imap.go

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package imap
66

77
import (
8+
"context"
89
"errors"
910
"io"
1011
"io/ioutil"
@@ -28,16 +29,29 @@ func init() {
2829
charset.RegisterEncoding("gb18030", simplifiedchinese.GB18030)
2930
}
3031

32+
var testMode bool
33+
3134
// Client an imap clientor
3235
type Client struct {
33-
Client *client.Client
36+
Client ClientPort
3437
UserName string
3538
Passwd string
3639
Addr string
3740
IsTLS bool
3841
Lock sync.Mutex
3942
}
4043

44+
// ClientPort client port to imap server or test code
45+
type ClientPort interface {
46+
Login(username, password string) error
47+
Logout() error
48+
Select(name string, readOnly bool) (*imap.MailboxStatus, error)
49+
Search(criteria *imap.SearchCriteria) (seqNums []uint32, err error)
50+
Store(seqset *imap.SeqSet, item imap.StoreItem, value interface{}, ch chan *imap.Message) error
51+
Expunge(ch chan uint32) error
52+
Fetch(seqset *imap.SeqSet, items []imap.FetchItem, ch chan *imap.Message) error
53+
}
54+
4155
// ClientInitOpt options to init an Client
4256
type ClientInitOpt struct {
4357
Addr string
@@ -73,6 +87,11 @@ func (c *Client) Login() error {
7387

7488
c.Lock.Lock()
7589

90+
// test mode
91+
if testMode {
92+
return c.Client.Login(c.UserName, c.Passwd)
93+
}
94+
7695
// Connect to server
7796
if c.IsTLS {
7897
c.Client, err = client.DialTLS(c.Addr, nil)
@@ -89,7 +108,6 @@ func (c *Client) Login() error {
89108
// LogOut LogOut from service
90109
func (c *Client) LogOut() error {
91110
err := c.Client.Logout()
92-
c.Client = nil
93111
c.Lock.Unlock()
94112
return err
95113
}
@@ -225,12 +243,34 @@ func (c *Client) FetchMail(id uint32, box string, requestBody bool) (*mail.Reade
225243
items := []imap.FetchItem{section.FetchItem()}
226244

227245
messages := make(chan *imap.Message, 1)
246+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
247+
defer cancel()
248+
249+
finished := false
228250

229251
go func() {
230252
err = c.Client.Fetch(seqSet, items, messages)
253+
finished = true
231254
}()
232255

233-
msg := <-messages
256+
var msg *imap.Message
257+
for finished {
258+
select {
259+
case msg, finished = <-messages:
260+
if msg != nil {
261+
if !finished {
262+
close(messages)
263+
}
264+
break
265+
}
266+
case <-ctx.Done():
267+
if !finished {
268+
close(messages)
269+
}
270+
break
271+
}
272+
}
273+
234274
if err != nil {
235275
return nil, err
236276
}

services/imap/imap_test.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright 2021 The Gitea Authors.
2+
// All rights reserved.
3+
// Use of this source code is governed by a MIT-style
4+
// license that can be found in the LICENSE file.
5+
6+
package imap
7+
8+
import (
9+
"fmt"
10+
"testing"
11+
12+
"code.gitea.io/gitea/modules/setting"
13+
"github.com/emersion/go-imap"
14+
"github.com/stretchr/testify/assert"
15+
)
16+
17+
var logs string
18+
19+
type testIMAPClient struct {
20+
t *testing.T
21+
}
22+
23+
func TestIMAP(t *testing.T) {
24+
// test GetUnReadMails
25+
logs = ""
26+
mails, err := c.GetUnReadMails(setting.MailReciveService.ReciveBox, 100)
27+
assert.NoError(t, err)
28+
if !assert.Equal(t, 2, len(mails)) {
29+
return
30+
}
31+
assert.Equal(t, "login: [email protected] 123456\n"+
32+
"Select: INBOX, false\n"+
33+
"Search: [\\Seen]\n"+
34+
"logout\n", logs)
35+
36+
// TODO
37+
// test handleReciveEmail
38+
// c.Client.(*testIMAPClient).t = t
39+
40+
// for _, mail := range mails {
41+
// logs = ""
42+
// if !assert.NoError(t, mail.LoadHeader([]string{"From", "To", "In-Reply-To", "References"})) {
43+
// return
44+
// }
45+
// if !assert.NoError(t, handleReciveEmail(mail)) {
46+
// return
47+
// }
48+
// assert.Equal(t, "", logs)
49+
// }
50+
}
51+
52+
func (c *testIMAPClient) Login(username, password string) error {
53+
logs += "login: " + username + " " + password + "\n"
54+
return nil
55+
}
56+
57+
func (c *testIMAPClient) Logout() error {
58+
logs += "logout\n"
59+
return nil
60+
}
61+
62+
func (c *testIMAPClient) Select(name string, readOnly bool) (*imap.MailboxStatus, error) {
63+
logs += fmt.Sprintf("Select: %v, %v\n", name, readOnly)
64+
if name != "INBOX" {
65+
return nil, fmt.Errorf("not found mail box")
66+
}
67+
68+
return nil, nil
69+
}
70+
71+
func (c *testIMAPClient) Search(criteria *imap.SearchCriteria) (seqNums []uint32, err error) {
72+
logs += fmt.Sprintf("Search: %v\n", criteria.WithoutFlags)
73+
74+
return []uint32{1, 2}, nil
75+
}
76+
77+
func (c *testIMAPClient) Store(seqset *imap.SeqSet, item imap.StoreItem, value interface{}, ch chan *imap.Message) error {
78+
logs += "Store\n"
79+
return nil
80+
}
81+
82+
func (c *testIMAPClient) Expunge(ch chan uint32) error {
83+
logs += "Expunge\n"
84+
return nil
85+
}
86+
87+
var testMails []string
88+
89+
func (c *testIMAPClient) Fetch(seqset *imap.SeqSet, items []imap.FetchItem, ch chan *imap.Message) error {
90+
defer close(ch)
91+
92+
// logs += fmt.Sprintf("Fetch: %v, %v\n", seqset.String(), items)
93+
// if len(seqset.Set) != 1 {
94+
// return nil
95+
// }
96+
// if seqset.Set[0].Start < 1 || seqset.Set[0].Start > 2 {
97+
// return nil
98+
// }
99+
100+
// if testMails == nil {
101+
// // load test data
102+
// testMails = make([]string, 2)
103+
// issue1 := models.AssertExistsAndLoadBean(c.t, &models.Issue{ID: 1}).(*models.Issue)
104+
// // comment2 := models.AssertExistsAndLoadBean(c.t, &models.Comment{ID: 2}).(*models.Comment)
105+
// user2 := models.AssertExistsAndLoadBean(c.t, &models.User{ID: 2}).(*models.User)
106+
107+
// testMails[0] = "From: " + user2.Email + "\r\n" +
108+
// "To: [email protected]\r\n" +
109+
// "Subject: Re: " + issue1.Title + "\r\n" +
110+
// "Date: Wed, 11 May 2016 14:31:59 +0000\r\n" +
111+
// "Message-ID: <0000000@localhost/>\r\n" +
112+
// "" +
113+
// "Content-Type: text/plain\r\n" +
114+
// "\r\n" +
115+
// "test reply\r\n" +
116+
// "----- origin mail ------\r\n" +
117+
// issue1.Content
118+
// }
119+
120+
return nil
121+
}

services/imap/mail_reciver.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ func NewContext() {
5757
}
5858

5959
func handleReciveEmail(m *Mail) error {
60-
from := m.Heads["From"][0].Address
60+
fromEmail, ok := m.Heads["From"]
61+
if !ok || len(fromEmail) < 1 {
62+
return nil
63+
}
64+
from := fromEmail[0].Address
6165
doer, err := models.GetUserByEmail(from)
6266
if err != nil {
6367
if models.IsErrUserNotExist(err) {

services/imap/main_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2021 The Gitea Authors.
2+
// All rights reserved.
3+
// Use of this source code is governed by a MIT-style
4+
// license that can be found in the LICENSE file.
5+
6+
package imap
7+
8+
import (
9+
"path/filepath"
10+
"testing"
11+
12+
"code.gitea.io/gitea/models"
13+
"code.gitea.io/gitea/modules/setting"
14+
)
15+
16+
func TestMain(m *testing.M) {
17+
// init test config
18+
testMode = true
19+
setting.MailReciveService = &setting.MailReciver{
20+
ReciveEmail: "[email protected]",
21+
ReciveBox: "INBOX",
22+
QueueLength: 100,
23+
Host: "127.0.0.1:1313",
24+
25+
Passwd: "123456",
26+
IsTLSEnabled: false,
27+
DeleteRodeMail: true,
28+
}
29+
30+
c = new(Client)
31+
32+
c.UserName = setting.MailReciveService.User
33+
c.Passwd = setting.MailReciveService.Passwd
34+
c.Addr = setting.MailReciveService.Host
35+
c.IsTLS = setting.MailReciveService.IsTLSEnabled
36+
c.Client = new(testIMAPClient)
37+
38+
models.MainTest(m, filepath.Join("..", ".."))
39+
}

0 commit comments

Comments
 (0)