223 lines
6.6 KiB
Go
223 lines
6.6 KiB
Go
package v1
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/stretchr/testify/suite"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
|
|
"github.com/gochat/gochat/internal/model"
|
|
"github.com/gochat/gochat/internal/repository"
|
|
"github.com/gochat/gochat/internal/service"
|
|
)
|
|
|
|
// ContactInboxHandlerTestSuite tests ContactInboxHandler with real SQLite DB.
|
|
type ContactInboxHandlerTestSuite struct {
|
|
suite.Suite
|
|
|
|
db *gorm.DB
|
|
router *gin.Engine
|
|
handler *ContactInboxHandler
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) SetupSuite() {
|
|
gin.SetMode(gin.TestMode)
|
|
|
|
db, err := gorm.Open(sqlite.Open("file::memory:"), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
s.Require().NoError(err, "failed to open SQLite test database")
|
|
|
|
// Auto-migrate required models (including FK dependencies)
|
|
s.Require().NoError(db.AutoMigrate(
|
|
&model.Account{},
|
|
&model.Inbox{},
|
|
&model.Contact{},
|
|
&model.ContactInbox{},
|
|
), "failed to auto-migrate models")
|
|
s.db = db
|
|
|
|
repo := repository.NewContactInboxRepo(db)
|
|
svc := service.NewContactInboxService(repo)
|
|
s.handler = NewContactInboxHandler(svc)
|
|
|
|
r := gin.New()
|
|
s.router = r
|
|
|
|
accounts := r.Group("/api/v1/accounts/:id")
|
|
{
|
|
accounts.GET("/contact_inboxes/filter", s.handler.Filter)
|
|
}
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TearDownSuite() {
|
|
sqlDB, err := s.db.DB()
|
|
if err == nil {
|
|
sqlDB.Close()
|
|
}
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) SetupTest() {
|
|
s.db.Exec("DELETE FROM contact_inboxes")
|
|
s.db.Exec("DELETE FROM contacts")
|
|
s.db.Exec("DELETE FROM inboxes")
|
|
s.db.Exec("DELETE FROM accounts")
|
|
}
|
|
|
|
// helper: create an account
|
|
func (s *ContactInboxHandlerTestSuite) createAccount(name string) *model.Account {
|
|
a := &model.Account{Name: name}
|
|
s.Require().NoError(s.db.Create(a).Error)
|
|
return a
|
|
}
|
|
|
|
// helper: create an inbox scoped to an account
|
|
func (s *ContactInboxHandlerTestSuite) createInbox(accountID uint, name string) *model.Inbox {
|
|
i := &model.Inbox{AccountID: accountID, Name: name, ChannelType: "channel_email"}
|
|
s.Require().NoError(s.db.Create(i).Error)
|
|
return i
|
|
}
|
|
|
|
// helper: create a contact scoped to an account
|
|
func (s *ContactInboxHandlerTestSuite) createContact(accountID uint, name string) *model.Contact {
|
|
c := &model.Contact{AccountID: accountID, Name: name}
|
|
s.Require().NoError(s.db.Create(c).Error)
|
|
return c
|
|
}
|
|
|
|
// helper: create a contact_inbox record directly via DB
|
|
func (s *ContactInboxHandlerTestSuite) createContactInbox(contactID, inboxID uint, sourceID string) *model.ContactInbox {
|
|
ci := &model.ContactInbox{
|
|
ContactID: contactID,
|
|
InboxID: inboxID,
|
|
SourceID: sourceID,
|
|
HMACToken: "test_hmac",
|
|
PubsubToken: "test_pubsub",
|
|
}
|
|
s.Require().NoError(s.db.Create(ci).Error)
|
|
return ci
|
|
}
|
|
|
|
// --- Filter tests ---
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_InvalidAccountID() {
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/v1/accounts/abc/contact_inboxes/filter", nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusBadRequest, w.Code)
|
|
|
|
var body map[string]interface{}
|
|
s.NoError(json.Unmarshal(w.Body.Bytes(), &body))
|
|
s.Contains(body, "error")
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_EmptyResult() {
|
|
a := s.createAccount("TestAccount")
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet,
|
|
"/api/v1/accounts/"+fmt.Sprintf("%d", a.ID)+"/contact_inboxes/filter", nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
|
|
var body map[string]interface{}
|
|
s.NoError(json.Unmarshal(w.Body.Bytes(), &body))
|
|
s.NotNil(body["contact_inboxes"])
|
|
cis := body["contact_inboxes"].([]interface{})
|
|
s.Len(cis, 0)
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_WithResults() {
|
|
a := s.createAccount("TestAccount")
|
|
i := s.createInbox(a.ID, "TestInbox")
|
|
c := s.createContact(a.ID, "TestContact")
|
|
s.createContactInbox(c.ID, i.ID, "src123")
|
|
|
|
w := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet,
|
|
"/api/v1/accounts/"+fmt.Sprintf("%d", a.ID)+"/contact_inboxes/filter", nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
|
|
var body map[string]interface{}
|
|
s.NoError(json.Unmarshal(w.Body.Bytes(), &body))
|
|
s.NotNil(body["contact_inboxes"])
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_WithInboxIDFilter() {
|
|
a := s.createAccount("TestAccount")
|
|
i1 := s.createInbox(a.ID, "Inbox1")
|
|
i2 := s.createInbox(a.ID, "Inbox2")
|
|
c := s.createContact(a.ID, "TestContact")
|
|
s.createContactInbox(c.ID, i1.ID, "src1")
|
|
s.createContactInbox(c.ID, i2.ID, "src2")
|
|
|
|
w := httptest.NewRecorder()
|
|
url := "/api/v1/accounts/" + fmt.Sprintf("%d", a.ID) +
|
|
"/contact_inboxes/filter?inbox_id=" + fmt.Sprintf("%d", i1.ID)
|
|
req := httptest.NewRequest(http.MethodGet, url, nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_WithContactIDFilter() {
|
|
a := s.createAccount("TestAccount")
|
|
i := s.createInbox(a.ID, "Inbox")
|
|
c1 := s.createContact(a.ID, "Contact1")
|
|
c2 := s.createContact(a.ID, "Contact2")
|
|
s.createContactInbox(c1.ID, i.ID, "src1")
|
|
s.createContactInbox(c2.ID, i.ID, "src2")
|
|
|
|
w := httptest.NewRecorder()
|
|
url := "/api/v1/accounts/" + fmt.Sprintf("%d", a.ID) +
|
|
"/contact_inboxes/filter?contact_id=" + fmt.Sprintf("%d", c1.ID)
|
|
req := httptest.NewRequest(http.MethodGet, url, nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_WithSourceIDFilter() {
|
|
a := s.createAccount("TestAccount")
|
|
i := s.createInbox(a.ID, "Inbox")
|
|
c := s.createContact(a.ID, "Contact")
|
|
s.createContactInbox(c.ID, i.ID, "special_source")
|
|
|
|
w := httptest.NewRecorder()
|
|
url := "/api/v1/accounts/" + fmt.Sprintf("%d", a.ID) +
|
|
"/contact_inboxes/filter?source_id=special_source"
|
|
req := httptest.NewRequest(http.MethodGet, url, nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
}
|
|
|
|
func (s *ContactInboxHandlerTestSuite) TestFilter_Pagination() {
|
|
a := s.createAccount("TestAccount")
|
|
i := s.createInbox(a.ID, "Inbox")
|
|
c := s.createContact(a.ID, "Contact")
|
|
|
|
for j := 0; j < 5; j++ {
|
|
s.createContactInbox(c.ID, i.ID, "src"+fmt.Sprintf("%d", j))
|
|
}
|
|
|
|
w := httptest.NewRecorder()
|
|
url := "/api/v1/accounts/" + fmt.Sprintf("%d", a.ID) +
|
|
"/contact_inboxes/filter?page=1&page_size=2"
|
|
req := httptest.NewRequest(http.MethodGet, url, nil)
|
|
s.router.ServeHTTP(w, req)
|
|
s.Equal(http.StatusOK, w.Code)
|
|
|
|
var body map[string]interface{}
|
|
s.NoError(json.Unmarshal(w.Body.Bytes(), &body))
|
|
meta := body["meta"].(map[string]interface{})
|
|
s.Equal(float64(5), meta["count"])
|
|
}
|
|
|
|
func TestContactInboxHandlerTestSuite(t *testing.T) {
|
|
suite.Run(t, new(ContactInboxHandlerTestSuite))
|
|
} |