@ -0,0 +1,255 @@ | |||
package Messages_test | |||
import ( | |||
"encoding/base64" | |||
"encoding/json" | |||
"fmt" | |||
"io/ioutil" | |||
"net/http" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests" | |||
) | |||
func Test_ConversationsList(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
nameCiphertext, err := key.AesEncrypt([]byte("Test conversation")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
twoUserCiphertext, err := key.AesEncrypt([]byte("false")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
messageThread := Models.ConversationDetail{ | |||
Name: base64.StdEncoding.EncodeToString(nameCiphertext), | |||
TwoUser: base64.StdEncoding.EncodeToString(twoUserCiphertext), | |||
} | |||
err = Database.CreateConversationDetail(&messageThread) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
conversationDetailIDCiphertext, err := key.AesEncrypt([]byte(messageThread.ID.String())) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
adminCiphertext, err := key.AesEncrypt([]byte("true")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
pubKey := Seeder.GetPubKey() | |||
messageThreadUser := Models.UserConversation{ | |||
UserID: u.ID, | |||
ConversationDetailID: base64.StdEncoding.EncodeToString(conversationDetailIDCiphertext), | |||
Admin: base64.StdEncoding.EncodeToString(adminCiphertext), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, pubKey), | |||
), | |||
} | |||
err = Database.CreateUserConversation(&messageThreadUser) | |||
req, _ := http.NewRequest("GET", ts.URL+"/api/v1/auth/conversations", nil) | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
requestBody, err := ioutil.ReadAll(resp.Body) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var conversations []Models.UserConversation | |||
json.Unmarshal(requestBody, &conversations) | |||
if len(conversations) != 1 { | |||
t.Errorf("Expected %d, recieved %d", 1, len(conversations)) | |||
} | |||
conv := conversations[0] | |||
decodedId, err := base64.StdEncoding.DecodeString(conv.ConversationDetailID) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
decrypedId, err := key.AesDecrypt(decodedId) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
req, _ = http.NewRequest( | |||
"GET", | |||
ts.URL+"/api/v1/auth/conversation_details?conversation_detail_ids="+string(decrypedId), | |||
nil, | |||
) | |||
resp, err = client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
var conversationDetails []Models.ConversationDetail | |||
requestBody, err = ioutil.ReadAll(resp.Body) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
json.Unmarshal(requestBody, &conversationDetails) | |||
if len(conversationDetails) != 1 { | |||
t.Errorf("Expected %d, recieved %d", 1, len(conversations)) | |||
} | |||
decodedName, err := base64.StdEncoding.DecodeString(conversationDetails[0].Name) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
decrypedName, err := key.AesDecrypt(decodedName) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
if string(decrypedName) != "Test conversation" { | |||
t.Errorf("Expected %s, recieved %s", "Test converation", string(decrypedName)) | |||
} | |||
} | |||
func Test_ConversationsListPagination(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
for i := 0; i < 40; i++ { | |||
nameCiphertext, err := key.AesEncrypt([]byte( | |||
fmt.Sprintf("Test conversation %d", i), | |||
)) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
twoUserCiphertext, err := key.AesEncrypt([]byte("false")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
messageThread := Models.ConversationDetail{ | |||
Name: base64.StdEncoding.EncodeToString(nameCiphertext), | |||
TwoUser: base64.StdEncoding.EncodeToString(twoUserCiphertext), | |||
} | |||
err = Database.CreateConversationDetail(&messageThread) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
conversationDetailIDCiphertext, err := key.AesEncrypt([]byte(messageThread.ID.String())) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
adminCiphertext, err := key.AesEncrypt([]byte("true")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
pubKey := Seeder.GetPubKey() | |||
messageThreadUser := Models.UserConversation{ | |||
UserID: u.ID, | |||
ConversationDetailID: base64.StdEncoding.EncodeToString(conversationDetailIDCiphertext), | |||
Admin: base64.StdEncoding.EncodeToString(adminCiphertext), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, pubKey), | |||
), | |||
} | |||
err = Database.CreateUserConversation(&messageThreadUser) | |||
} | |||
req, _ := http.NewRequest("GET", ts.URL+"/api/v1/auth/conversations?page=0", nil) | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusOK { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
requestBody, err := ioutil.ReadAll(resp.Body) | |||
if err != nil { | |||
t.Errorf("Expected %d, recieved %d", http.StatusOK, resp.StatusCode) | |||
return | |||
} | |||
var conversations []Models.UserConversation | |||
json.Unmarshal(requestBody, &conversations) | |||
if len(conversations) != 20 { | |||
t.Errorf("Expected %d, recieved %d", 1, len(conversations)) | |||
} | |||
} |
@ -0,0 +1,129 @@ | |||
package Messages_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"net/http" | |||
"testing" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests" | |||
"github.com/gofrs/uuid" | |||
) | |||
func Test_CreateConversation(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
nameCiphertext, err := key.AesEncrypt([]byte("Test conversation")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
twoUserCiphertext, err := key.AesEncrypt([]byte("false")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
id, err := uuid.NewV4() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
conversationDetailIDCiphertext, err := key.AesEncrypt([]byte(id.String())) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
adminCiphertext, err := key.AesEncrypt([]byte("true")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
userIDCiphertext, err := key.AesEncrypt([]byte(u.ID.String())) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
usernameCiphertext, err := key.AesEncrypt([]byte(u.Username)) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
pubKey := Seeder.GetPubKey() | |||
d := struct { | |||
ID string `json:"id"` | |||
Name string `json:"name"` | |||
TwoUser string `json:"two_user"` | |||
Users []Models.ConversationDetailUser `json:"users"` | |||
UserConversations []Models.UserConversation `json:"user_conversations"` | |||
}{ | |||
ID: id.String(), | |||
Name: base64.StdEncoding.EncodeToString(nameCiphertext), | |||
TwoUser: base64.StdEncoding.EncodeToString(twoUserCiphertext), | |||
Users: []Models.ConversationDetailUser{ | |||
{ | |||
ConversationDetailID: id, | |||
UserID: base64.StdEncoding.EncodeToString(userIDCiphertext), | |||
Username: base64.StdEncoding.EncodeToString(usernameCiphertext), | |||
AssociationKey: "", | |||
PublicKey: "", | |||
Admin: base64.StdEncoding.EncodeToString(adminCiphertext), | |||
}, | |||
}, | |||
UserConversations: []Models.UserConversation{ | |||
{ | |||
UserID: u.ID, | |||
ConversationDetailID: base64.StdEncoding.EncodeToString(conversationDetailIDCiphertext), | |||
Admin: base64.StdEncoding.EncodeToString(adminCiphertext), | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(key.Key, pubKey), | |||
), | |||
}, | |||
}, | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/conversations", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusNoContent { | |||
t.Errorf("Expected %d, recieved %d", http.StatusNoContent, resp.StatusCode) | |||
} | |||
var c Models.ConversationDetail | |||
err = Database.DB.First(&c, "id = ?", id.String()).Error | |||
if err != nil { | |||
t.Errorf("Expected conversation detail record, received %s", err.Error()) | |||
return | |||
} | |||
} |
@ -0,0 +1,131 @@ | |||
package Messages_test | |||
import ( | |||
"bytes" | |||
"encoding/base64" | |||
"encoding/json" | |||
"net/http" | |||
"testing" | |||
"time" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Tests" | |||
"github.com/gofrs/uuid" | |||
) | |||
func Test_CreateMessage(t *testing.T) { | |||
client, ts, err := Tests.InitTestEnv() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
u, err := Database.GetUserByUsername("test") | |||
key, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
dataCiphertext, err := key.AesEncrypt([]byte("Test message...")) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
senderIDCiphertext, err := key.AesEncrypt([]byte(u.ID.String())) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
id, err := uuid.NewV4() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
id2, err := uuid.NewV4() | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
d := []struct { | |||
MessageData struct { | |||
ID uuid.UUID `json:"id"` | |||
Data string `json:"data"` | |||
SenderID string `json:"sender_id"` | |||
SymmetricKey string `json:"symmetric_key"` | |||
} `json:"message_data"` | |||
Messages []struct { | |||
ID uuid.UUID `json:"id"` | |||
MessageDataID uuid.UUID `json:"message_data_id"` | |||
SymmetricKey string `json:"symmetric_key"` | |||
AssociationKey string `json:"association_key"` | |||
Expiry time.Time `json:"expiry"` | |||
} `json:"message"` | |||
}{ | |||
{ | |||
MessageData: struct { | |||
ID uuid.UUID `json:"id"` | |||
Data string `json:"data"` | |||
SenderID string `json:"sender_id"` | |||
SymmetricKey string `json:"symmetric_key"` | |||
}{ | |||
ID: id, | |||
Data: base64.StdEncoding.EncodeToString(dataCiphertext), | |||
SenderID: base64.StdEncoding.EncodeToString(senderIDCiphertext), | |||
SymmetricKey: "", | |||
}, | |||
Messages: []struct { | |||
ID uuid.UUID `json:"id"` | |||
MessageDataID uuid.UUID `json:"message_data_id"` | |||
SymmetricKey string `json:"symmetric_key"` | |||
AssociationKey string `json:"association_key"` | |||
Expiry time.Time `json:"expiry"` | |||
}{ | |||
{ | |||
ID: id2, | |||
MessageDataID: id, | |||
SymmetricKey: "", | |||
AssociationKey: "", | |||
Expiry: time.Now(), | |||
}, | |||
}, | |||
}, | |||
} | |||
jsonStr, _ := json.Marshal(d) | |||
req, _ := http.NewRequest("POST", ts.URL+"/api/v1/auth/message", bytes.NewBuffer(jsonStr)) | |||
req.Header.Set("Content-Type", "application/json") | |||
resp, err := client.Do(req) | |||
if err != nil { | |||
t.Errorf("Expected nil, recieved %s", err.Error()) | |||
return | |||
} | |||
if resp.StatusCode != http.StatusNoContent { | |||
t.Errorf("Expected %d, recieved %d", http.StatusNoContent, resp.StatusCode) | |||
return | |||
} | |||
var m Models.Message | |||
err = Database.DB.First(&m).Error | |||
if err != nil { | |||
t.Errorf("Expected conversation detail record, received %s", err.Error()) | |||
return | |||
} | |||
var md Models.MessageData | |||
err = Database.DB.First(&md).Error | |||
if err != nil { | |||
t.Errorf("Expected conversation detail record, received %s", err.Error()) | |||
return | |||
} | |||
} |
@ -0,0 +1,87 @@ | |||
package Tests | |||
import ( | |||
"encoding/base64" | |||
"io/ioutil" | |||
"log" | |||
"net/http" | |||
"net/http/cookiejar" | |||
"net/http/httptest" | |||
"net/url" | |||
"time" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Api/Auth" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Database/Seeder" | |||
"git.tovijaeschke.xyz/tovi/Capsule/Backend/Models" | |||
"github.com/gorilla/mux" | |||
) | |||
// InitTestEnv initializes the test environment | |||
// client is used for making authenticated requests | |||
// ts is the testing server | |||
// err, in case it fails ¯\_(ツ)_/¯ | |||
func InitTestEnv() (*http.Client, *httptest.Server, error) { | |||
log.SetOutput(ioutil.Discard) | |||
Database.InitTest() | |||
r := mux.NewRouter() | |||
Api.InitAPIEndpoints(r) | |||
ts := httptest.NewServer(r) | |||
userKey, err := Seeder.GenerateAesKey() | |||
if err != nil { | |||
return http.DefaultClient, ts, err | |||
} | |||
pubKey := Seeder.GetPubKey() | |||
p, _ := Auth.HashPassword("password") | |||
u := Models.User{ | |||
Username: "test", | |||
Password: p, | |||
AsymmetricPublicKey: Seeder.PublicKey, | |||
AsymmetricPrivateKey: Seeder.EncryptedPrivateKey, | |||
SymmetricKey: base64.StdEncoding.EncodeToString( | |||
Seeder.EncryptWithPublicKey(userKey.Key, pubKey), | |||
), | |||
} | |||
err = Database.CreateUser(&u) | |||
if err != nil { | |||
return http.DefaultClient, ts, err | |||
} | |||
session := Models.Session{ | |||
UserID: u.ID, | |||
Expiry: time.Now().Add(12 * time.Hour), | |||
} | |||
err = Database.CreateSession(&session) | |||
if err != nil { | |||
return http.DefaultClient, ts, err | |||
} | |||
jar, err := cookiejar.New(nil) | |||
url, _ := url.Parse(ts.URL) | |||
jar.SetCookies( | |||
url, | |||
[]*http.Cookie{ | |||
{ | |||
Name: "session_token", | |||
Value: session.ID.String(), | |||
MaxAge: 300, | |||
}, | |||
}, | |||
) | |||
client := &http.Client{ | |||
Jar: jar, | |||
} | |||
return client, ts, err | |||
} |
@ -1,3 +1,3 @@ | |||
#!/bin/sh | |||
docker-compose exec server sh -c "cd /app && go test -v ./..." | |||
docker-compose exec server sh -c "cd /app && go test -p 1 -v ./..." |