Skip to content

Commit

Permalink
test(backend): fix test for nocodb related
Browse files Browse the repository at this point in the history
  • Loading branch information
aldy505 committed Mar 11, 2024
1 parent b041089 commit 9bd287c
Show file tree
Hide file tree
Showing 16 changed files with 397 additions and 212 deletions.
1 change: 1 addition & 0 deletions backend/nocodb/create_table_records.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ func (c *Client) CreateTableRecords(ctx context.Context, tableId string, records
}

request.Header.Add("xc-auth", c.apiToken)
request.Header.Add("Content-Type", "application/json")

response, err := c.httpClient.Do(request)
if err != nil {
Expand Down
128 changes: 128 additions & 0 deletions backend/nocodb/nocodb_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package nocodb_test

import (
"context"
"crypto/rand"
"encoding/base64"
"net/http/httptest"
"os"
"strconv"
"testing"
"time"

"conf/nocodb"
"conf/nocodb/nocodbmock"
"github.com/rs/zerolog/log"
)

var client *nocodb.Client
var tableId string

func TestMain(m *testing.M) {
baseUrl := os.Getenv("NOCODB_BASE_URL")
apiToken := os.Getenv("NOCODB_API_KEY")
tableId = os.Getenv("NOCODB_TABLE_ID")
if tableId == "" {
tableId = "aabbcc"
}

var err error = nil
var mockServer *httptest.Server = nil
if baseUrl != "" && apiToken != "" {
client, err = nocodb.NewClient(nocodb.ClientOptions{
ApiToken: apiToken,
BaseUrl: baseUrl,
})
if err != nil {
log.Fatal().Err(err).Msg("creating nocodb client")
return
}
} else {
mockServer, err = nocodbmock.NewNocoDBMockServer()
if err != nil {
mockServer.Close()
log.Fatal().Err(err).Msg("creating mock server")
return
}

client, err = nocodb.NewClient(nocodb.ClientOptions{
ApiToken: "testing",
BaseUrl: mockServer.URL,
HttpClient: mockServer.Client(),
})
if err != nil {
log.Fatal().Err(err).Msg("creating nocodb client")
return
}
}

exitCode := m.Run()

if mockServer != nil {
mockServer.Close()
}

os.Exit(exitCode)
}

type testBody struct {
Id int64 `json:"Id,omitempty"`
Title string
Age int
RandomText string
}

func TestIntegration(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

randomBytes := make([]byte, 16)
rand.Read(randomBytes)
randomText := base64.StdEncoding.EncodeToString(randomBytes)
payload := testBody{
Title: "John Doe",
Age: 49,
RandomText: randomText,
}

err := client.CreateTableRecords(ctx, tableId, []any{payload})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

var outPayload []testBody
pageInfo, err := client.ListTableRecords(ctx, tableId, &outPayload, nocodb.ListTableRecordOptions{})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

found := false
foundPayload := testBody{}
for _, out := range outPayload {
if out.RandomText == randomText {
found = true
foundPayload = out
}
}
if !found {
t.Errorf("expecting just inserted entry to be found, got not found")
}
if pageInfo.TotalRows <= 0 {
t.Errorf("expecting pageInfo.TotalRows to be a positive number greater than one, got %d", pageInfo.TotalRows)
}

err = client.UpdateTableRecords(ctx, tableId, []any{map[string]any{"Id": foundPayload.Id, "Age": 320}})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

var anotherOutPayload testBody
err = client.ReadTableRecords(ctx, tableId, strconv.FormatInt(foundPayload.Id, 10), &anotherOutPayload, nocodb.ReadTableRecordsOptions{})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

if anotherOutPayload.Age != 320 {
t.Errorf("expecting Age to be updated to 320, got %d", anotherOutPayload.Age)
}
}
35 changes: 33 additions & 2 deletions backend/nocodb/nocodbmock/inmemory_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,22 @@ func (s *storage) GetByRecordId(tableId string, recordId int64) (record map[stri
}

for _, record := range records {
if record["Id"] == recordId {
var id int64
switch v := record["Id"].(type) {
case float64:
id = int64(v)
break
case float32:
id = int64(v)
break
case int:
id = int64(v)
break
case int64:
id = v
break
}
if recordId == id {
return record, nil
}
}
Expand Down Expand Up @@ -79,7 +94,23 @@ func (s *storage) Update(tableId string, records []map[string]any) (ids []int64,
for i := 0; i < len(oldRecords); i++ {
// I know that this is O(n^2) but because this is a mock, I don't really care
for _, record := range records {
if oldRecords[i]["Id"] == record["Id"] {
var recordId int64
switch v := record["Id"].(type) {
case float64:
recordId = int64(v)
break
case float32:
recordId = int64(v)
break
case int:
recordId = int64(v)
break
case int64:
recordId = v
break
}

if oldRecords[i]["Id"] == recordId {
// Found one
for key, value := range record {
oldRecords[i][key] = value
Expand Down
3 changes: 2 additions & 1 deletion backend/nocodb/nocodbmock/nocodbmock.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package nocodbmock

import (
"encoding/json"
"errors"
"net/http"
"net/http/httptest"
"strconv"
Expand Down Expand Up @@ -38,7 +39,7 @@ func NewNocoDBMockServer() (*httptest.Server, error) {
}

records, err := documentStorage.GetByTableId(tableId)
if err != nil {
if err != nil && !errors.Is(err, errNotFound) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadRequest)
_ = json.NewEncoder(w).Encode(errorResponse{Message: "BadRequest [ERROR]: " + err.Error()})
Expand Down
3 changes: 2 additions & 1 deletion backend/nocodb/update_table_records.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ func (c *Client) UpdateTableRecords(ctx context.Context, tableId string, records
}

request.Header.Add("xc-auth", c.apiToken)

request.Header.Add("Content-Type", "application/json")

response, err := c.httpClient.Do(request)
if err != nil {
return fmt.Errorf("executing http request: %w", err)
Expand Down
2 changes: 1 addition & 1 deletion backend/server_handler_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func ServerHandlerAction(ctx *cli.Context) error {
SmtpPassword: config.Mailer.Password,
})

ticketDomain, err := ticketing.NewTicketDomain(database, bucket, signaturePrivateKey, signaturePublicKey, mailSender)
ticketDomain, err := ticketing.NewTicketDomain(database, bucket, signaturePrivateKey, signaturePublicKey, mailSender, config.Database.TicketingTableId)
if err != nil {
return fmt.Errorf("creating ticket domain: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion backend/ticketing/store_payment_receipt.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (t *TicketDomain) StorePaymentReceipt(ctx context.Context, user user.User,
return fmt.Errorf("uploading to bucket storage: %w", err)
}

err = t.db.CreateTableRecords(ctx, "TODO: Table id", []any{Ticketing{
err = t.db.CreateTableRecords(ctx, t.tableId, []any{Ticketing{
Email: user.Email,
ReceiptPhotoPath: blobKey,
Paid: false,
Expand Down
95 changes: 95 additions & 0 deletions backend/ticketing/store_payment_receipt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package ticketing_test

import (
"context"
"crypto/ed25519"
"crypto/rand"
"errors"
"strings"
"testing"
"time"

"conf/ticketing"
"conf/user"
)

func TestTicketDomain_StorePaymentReceipt(t *testing.T) {
publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader)
if err != nil {
t.Fatalf("generating new ed25519 key: %s", err.Error())
return
}

ticketDomain, err := ticketing.NewTicketDomain(database, bucket, privateKey, publicKey, mailSender, tableId)
if err != nil {
t.Fatalf("creating a ticket domain instance: %s", err.Error())
}

userDomain, err := user.NewUserDomain(database, "testing")
if err != nil {
t.Fatalf("creating user domain instance: %s", err.Error())
}

t.Run("Invalid photo", func(t *testing.T) {
err := ticketDomain.StorePaymentReceipt(context.Background(), user.User{}, nil, "")
if err == nil {
t.Error("expecting an error, got nil instead")
}

var validationError *ticketing.ValidationError
if errors.As(err, &validationError) {
if len(validationError.Errors) != 2 {
t.Errorf("expecting two errors, got %d", len(validationError.Errors))
}
}
})

t.Run("Happy scenario", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

email := "[email protected]"
err := userDomain.CreateParticipant(ctx, user.CreateParticipantRequest{
Name: "John Doe",
Email: email,
})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

err = ticketDomain.StorePaymentReceipt(ctx, user.User{Email: email}, strings.NewReader("Hello world! This is not a photo. Yet this will be a text file."), "text/plain")
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}
})

t.Run("Update data if email already exists", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

email := "[email protected]"
err := userDomain.CreateParticipant(ctx, user.CreateParticipantRequest{
Name: "John Doe",
Email: email,
})
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

user := user.User{
Email: email,
}

// First attempt
err = ticketDomain.StorePaymentReceipt(ctx, user, strings.NewReader("Hello world! This is not a photo. Yet this will be a text file."), "text/plain")
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}

// Second attempt, should not return error
err = ticketDomain.StorePaymentReceipt(ctx, user, strings.NewReader("Hello world! This is not a photo. Yet this will be a text file."), "text/plain")
if err != nil {
t.Errorf("unexpected error: %s", err.Error())
}
})
}
8 changes: 7 additions & 1 deletion backend/ticketing/ticketing.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import (

type TicketDomain struct {
db *nocodb.Client
tableId string
bucket *blob.Bucket
privateKey *ed25519.PrivateKey
publicKey *ed25519.PublicKey
mailer *mailer.Mailer
}

func NewTicketDomain(db *nocodb.Client, bucket *blob.Bucket, privateKey ed25519.PrivateKey, publicKey ed25519.PublicKey, mailer *mailer.Mailer) (*TicketDomain, error) {
func NewTicketDomain(db *nocodb.Client, bucket *blob.Bucket, privateKey ed25519.PrivateKey, publicKey ed25519.PublicKey, mailer *mailer.Mailer, tableId string) (*TicketDomain, error) {
if db == nil {
return nil, fmt.Errorf("db is nil")
}
Expand All @@ -44,12 +45,17 @@ func NewTicketDomain(db *nocodb.Client, bucket *blob.Bucket, privateKey ed25519.
return nil, fmt.Errorf("mailer is nil")
}

if tableId == "" {
return nil, fmt.Errorf("tableId is nil")
}

return &TicketDomain{
db: db,
bucket: bucket,
privateKey: &privateKey,
publicKey: &publicKey,
mailer: mailer,
tableId: tableId,
}, nil
}

Expand Down
Loading

0 comments on commit 9bd287c

Please sign in to comment.