235 lines
6.0 KiB
Go
235 lines
6.0 KiB
Go
package test
|
||
|
||
import (
|
||
"bufio"
|
||
"bytes"
|
||
"context"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"io/ioutil"
|
||
"mime/multipart"
|
||
"net/http"
|
||
"os"
|
||
"strings"
|
||
"testing"
|
||
"time"
|
||
|
||
"heruvym/app"
|
||
"heruvym/model"
|
||
"heruvym/service"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
"github.com/themakers/bdd"
|
||
)
|
||
|
||
func TestTicket(t *testing.T) {
|
||
fmt.Println("start test")
|
||
ctx, cancel := context.WithCancel(context.Background())
|
||
defer cancel()
|
||
bdd.Scenario(t, "SupportChat", func(t *testing.T, runID string) {
|
||
go func() {
|
||
|
||
time.Sleep(3 * time.Second)
|
||
fmt.Println("start service")
|
||
_, err := app.New(ctx, app.Options{
|
||
MongoURI: "mongodb://mongo:27017",
|
||
NumberPortLocal: "1488",
|
||
LoggerDevMode: false,
|
||
MinioEndpoint: "minio:9000",
|
||
MinioAccessKey: "minioadmin",
|
||
MinioSecretKey: "minioadmin",
|
||
MongoDbTable: "profile",
|
||
MongoCollections: "profile,role",
|
||
})
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
}()
|
||
time.Sleep(time.Second * 5)
|
||
|
||
bdd.Act(t, "client", func() {
|
||
fmt.Println("client")
|
||
var (
|
||
token string
|
||
ticket service.CreateTicketResp
|
||
msgs = make(chan []byte)
|
||
)
|
||
bdd.Test(t, "CreateTicket", func() {
|
||
|
||
buf, err := json.Marshal(service.CreateTicketReq{
|
||
Title: "TestTitle",
|
||
Message: "test",
|
||
})
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
req, err := http.NewRequestWithContext(
|
||
ctx,
|
||
"POST",
|
||
"http://localhost:1488/support/create", bytes.NewBuffer(buf))
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
req.Header.Add(jwt_adapter.DefaultHeaderKey, "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJRCI6ImMxcDM0YjhqZHBmOG04Zm43cnIwIiwiU2Vzc2lvbiI6ImMxcDM0YjhqZHBmOG04Zm43cnJnIiwiVXNlciI6IiIsIlRhcmlmZiI6MCwiQ3JlYXRlZCI6MTYxODA5NjY4NTc4MCwiTGFzdFNlZW4iOjE2MTgwOTY2ODU3ODF9.ciJoJiOxzIPv0LY4h3rG8Tf3AsSBXXLcYEpyN9mIki0")
|
||
|
||
resp, err := http.DefaultClient.Do(req)
|
||
|
||
if err != nil {
|
||
assert.NoError(t, err)
|
||
}
|
||
|
||
if resp.StatusCode != http.StatusOK {
|
||
panic("NotAccepted")
|
||
}
|
||
|
||
token = resp.Header.Get(jwt_adapter.DefaultHeaderKey)
|
||
|
||
assert.NoError(t, json.NewDecoder(resp.Body).Decode(&ticket))
|
||
})
|
||
bdd.Test(t, "subscribe for tiket", func() {
|
||
client := &http.Client{}
|
||
|
||
r, err := http.NewRequest("GET", "http://localhost:1488/support/ticket?Authorization="+token+"&ticket="+ticket.Ticket, nil)
|
||
assert.NoError(t, err)
|
||
|
||
r.Header.Set("Accept", "text/event-stream")
|
||
r.Header.Set("Cache-Control", "no-cache")
|
||
r.Header.Set("Connection", "keep-alive")
|
||
resp, err := client.Do(r)
|
||
assert.NoError(t, err)
|
||
|
||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||
|
||
sc := bufio.NewScanner(resp.Body)
|
||
split := func(data []byte, atEOF bool) (int, []byte, error) {
|
||
if atEOF && len(data) == 0 {
|
||
return 0, nil, nil
|
||
}
|
||
|
||
if strings.Contains(string(data), ":ping") {
|
||
return 0, nil, nil
|
||
}
|
||
|
||
if len(data) <= 6 {
|
||
return 0, nil, errors.New(fmt.Sprintf("got bad body: %v", string(data)))
|
||
}
|
||
// Мы получили данные для обработки
|
||
// Начинаем с 6 байта, чтобы убрать "data: "
|
||
|
||
if i, nlen := containsDoubleNewline(data); i >= 0 {
|
||
return i + nlen, data[6:i], nil
|
||
}
|
||
|
||
// Если получен EOF, то мы получили все что необходимо
|
||
if atEOF {
|
||
return len(data), data, nil
|
||
}
|
||
|
||
return 0, nil, nil
|
||
}
|
||
sc.Split(split)
|
||
|
||
go func() {
|
||
for sc.Scan() {
|
||
body := sc.Bytes()
|
||
msgs <- body
|
||
fmt.Println("data from", string(body))
|
||
}
|
||
|
||
if err = sc.Err(); err != nil {
|
||
fmt.Println("scanner.Err()", err)
|
||
if err != bufio.ErrTooLong {
|
||
fmt.Println("toolong")
|
||
}
|
||
}
|
||
}()
|
||
|
||
})
|
||
bdd.Test(t, "send message", func() {
|
||
|
||
buf, err := json.Marshal(service.ReqPutMessage{
|
||
Message: "test",
|
||
TicketID: ticket.Ticket,
|
||
Lang: "ru",
|
||
})
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://localhost:1488/support/send", bytes.NewBuffer(buf))
|
||
assert.NoError(t, err)
|
||
|
||
req.Header.Add(jwt_adapter.DefaultHeaderKey, token)
|
||
resp, err := http.DefaultClient.Do(req)
|
||
assert.NoError(t, err)
|
||
|
||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||
|
||
var msg, channed model.Message
|
||
assert.NoError(t, json.NewDecoder(resp.Body).Decode(&msg))
|
||
err = json.Unmarshal(<-msgs, &channed)
|
||
assert.NoError(t, err)
|
||
assert.Equal(t, "test", channed.Message)
|
||
})
|
||
bdd.Test(t, "send file", func() {
|
||
body := &bytes.Buffer{}
|
||
writer := multipart.NewWriter(body)
|
||
|
||
partf, _ := writer.CreateFormFile("f.go", "f.go")
|
||
f, err := os.OpenFile("./main_test.go", os.O_RDWR, 0644)
|
||
assert.NoError(t, err)
|
||
io.Copy(partf, f)
|
||
|
||
assert.NoError(t, writer.WriteField("ticket", ticket.Ticket))
|
||
|
||
writer.Close()
|
||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://localhost:1488/support/sendFiles", body)
|
||
req.Header.Set("Content-Type", "multipart/form-data; boundary="+writer.Boundary())
|
||
|
||
req.Header.Add(jwt_adapter.DefaultHeaderKey, token)
|
||
|
||
resp, err := http.DefaultClient.Do(req)
|
||
assert.NoError(t, err)
|
||
assert.Equal(t, http.StatusOK, resp.StatusCode)
|
||
|
||
str, err := ioutil.ReadAll(resp.Body)
|
||
fmt.Println("resp files", err, string(str))
|
||
})
|
||
})
|
||
})
|
||
}
|
||
func containsDoubleNewline(data []byte) (int, int) {
|
||
// Ищем все возможные переносы строки
|
||
crcr := bytes.Index(data, []byte("\r\r"))
|
||
lflf := bytes.Index(data, []byte("\n\n"))
|
||
crlflf := bytes.Index(data, []byte("\r\n\n"))
|
||
lfcrlf := bytes.Index(data, []byte("\n\r\n"))
|
||
crlfcrlf := bytes.Index(data, []byte("\r\n\r\n"))
|
||
// Находим первый двойной перенос строки
|
||
minPos := minPosInt(crcr, minPosInt(lflf, minPosInt(crlflf, minPosInt(lfcrlf, crlfcrlf))))
|
||
// Определяем длину
|
||
nlen := 2
|
||
if minPos == crlfcrlf {
|
||
nlen = 4
|
||
} else if minPos == crlflf || minPos == lfcrlf {
|
||
nlen = 3
|
||
}
|
||
return minPos, nlen
|
||
}
|
||
|
||
func minPosInt(a, b int) int {
|
||
if a < 0 {
|
||
return b
|
||
}
|
||
if b < 0 {
|
||
return a
|
||
}
|
||
if a > b {
|
||
return b
|
||
}
|
||
return a
|
||
}
|