-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added tests for major pine methods and small improvement to rate limi…
…t implementation
- Loading branch information
1 parent
2613746
commit 63ed3fd
Showing
12 changed files
with
1,120 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,3 +23,5 @@ go.work.sum | |
|
||
# env file | ||
.env | ||
|
||
./uploads |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
"net/http" | ||
|
||
"github.com/BryanMwangi/pine" | ||
"github.com/BryanMwangi/pine/cors" | ||
) | ||
|
||
func main() { | ||
app := pine.New() | ||
|
||
app.Use(cors.New(cors.Config{ | ||
AllowedOrigins: []string{"*"}, | ||
})) | ||
|
||
app.Post("/upload", func(c *pine.Ctx) error { | ||
file, header, err := c.FormFile("file") | ||
if err != nil { | ||
return c.SendStatus(http.StatusInternalServerError) | ||
} | ||
defer file.Close() | ||
err = c.SaveFile(file, header) | ||
if err != nil { | ||
return c.SendStatus(http.StatusInternalServerError) | ||
} | ||
return c.SendString("successfully uploaded file: " + header.Filename) | ||
}) | ||
|
||
app.Get("/stream", func(c *pine.Ctx) error { | ||
return c.StreamFile("./benchmark.mp4") | ||
}) | ||
|
||
app.Get("/send", func(c *pine.Ctx) error { | ||
return c.SendFile("./server.log") | ||
}) | ||
|
||
log.Fatal(app.Start(":3001")) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
2024/09/29 22:18:57 INFO: Received ping | ||
2024/09/29 22:19:10 INFO: Received ping | ||
2024/09/29 22:19:16 INFO: Received ping | ||
2024/09/29 22:19:19 INFO: Received ping |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package pine | ||
|
||
import ( | ||
"bytes" | ||
"errors" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
) | ||
|
||
func TestBindJSON_Success(t *testing.T) { | ||
body := `{"name": "John", "age": 30}` | ||
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body)) | ||
ctx := &Ctx{Request: req} | ||
|
||
var data struct { | ||
Name string `json:"name"` | ||
Age int `json:"age"` | ||
} | ||
|
||
err := ctx.BindJSON(&data) | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
|
||
if data.Name != "John" || data.Age != 30 { | ||
t.Fatalf("expected name 'John' and age 30, got name '%s' and age %d", data.Name, data.Age) | ||
} | ||
} | ||
|
||
func TestBindJSON_InvalidJSON(t *testing.T) { | ||
body := `{"name": "John", "age":}` | ||
req := httptest.NewRequest(http.MethodPost, "/", bytes.NewBufferString(body)) | ||
ctx := &Ctx{Request: req} | ||
|
||
var data struct { | ||
Name string `json:"name"` | ||
Age int `json:"age"` | ||
} | ||
|
||
err := ctx.BindJSON(&data) | ||
if !errors.Is(err, ErrParse) { | ||
t.Fatalf("expected ErrParse, got %v", err) | ||
} | ||
} | ||
|
||
func TestBindParam_Success(t *testing.T) { | ||
ctx := Mock_Ctx() | ||
|
||
var id int | ||
err := ctx.BindParam("id", &id) | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
if id != 42 { | ||
t.Fatalf("expected id to be 42, got %d", id) | ||
} | ||
} | ||
|
||
func TestBindParam_NotFound(t *testing.T) { | ||
ctx := Mock_Ctx() | ||
|
||
var id int | ||
err := ctx.BindParam("missing", &id) | ||
if !errors.Is(err, ErrValidation) { | ||
t.Fatalf("expected ErrValidation, got %v", err) | ||
} | ||
} | ||
|
||
func TestBindQuery_Success(t *testing.T) { | ||
ctx := Mock_Ctx() | ||
|
||
var value string | ||
err := ctx.BindQuery("query", &value) | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
if value != "queryValue" { | ||
t.Fatalf("expected query value to be 'queryValue', got '%s'", value) | ||
} | ||
} | ||
|
||
func TestBindQuery_NotFound(t *testing.T) { | ||
ctx := Mock_Ctx() | ||
|
||
var value string | ||
err := ctx.BindQuery("missing", &value) | ||
if !errors.Is(err, ErrValidation) { | ||
t.Fatalf("expected ErrValidation, got %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
package pine | ||
|
||
import ( | ||
"encoding/json" | ||
"errors" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
"time" | ||
) | ||
|
||
func TestNewClient(t *testing.T) { | ||
client := NewClient() | ||
if client == nil { | ||
t.Fatal("expected non-nil client") | ||
} | ||
if client.Client == nil { | ||
t.Fatal("expected default http client") | ||
} | ||
} | ||
|
||
func TestNewClientWithTimeout(t *testing.T) { | ||
timeout := 2 * time.Second | ||
client := NewClientWithTimeout(timeout) | ||
if client == nil { | ||
t.Fatal("expected non-nil client") | ||
} | ||
if client.Client.Timeout != timeout { | ||
t.Fatalf("expected timeout to be %v, got %v", timeout, client.Client.Timeout) | ||
} | ||
} | ||
|
||
func TestRequest_JSON(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
testBody := map[string]string{"key": "value"} | ||
|
||
if err := req.JSON(testBody); err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
if req.body == nil { | ||
t.Fatal("expected body to be set") | ||
} | ||
|
||
expectedContentType := "application/json" | ||
if req.Header.Get("Content-Type") != expectedContentType { | ||
t.Fatalf("expected Content-Type to be %s, got %s", expectedContentType, req.Header.Get("Content-Type")) | ||
} | ||
|
||
var result map[string]string | ||
if err := json.NewDecoder(req.body).Decode(&result); err != nil { | ||
t.Fatalf("failed to decode body: %v", err) | ||
} | ||
if result["key"] != "value" { | ||
t.Errorf("expected key to be 'value', got %s", result["key"]) | ||
} | ||
} | ||
|
||
func TestRequest_SetHeaders(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
|
||
headers := map[string]string{"X-Custom-Header": "value"} | ||
req.SetHeaders(headers) | ||
|
||
if req.Header.Get("X-Custom-Header") != "value" { | ||
t.Fatalf("expected header X-Custom-Header to be 'value', got %s", req.Header.Get("X-Custom-Header")) | ||
} | ||
} | ||
|
||
func TestRequest_SetRequestURI(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
uri := "https://example.com/api" | ||
|
||
req.SetRequestURI(uri) | ||
if req.uri != uri { | ||
t.Fatalf("expected uri to be %s, got %s", uri, req.uri) | ||
} | ||
} | ||
|
||
func TestRequest_SetMethod(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
method := "GET" | ||
|
||
req.SetMethod(method) | ||
if req.method != method { | ||
t.Fatalf("expected method to be %s, got %s", method, req.method) | ||
} | ||
} | ||
|
||
func TestClient_SendRequest(t *testing.T) { | ||
// Setup a test server | ||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte("success")) | ||
})) | ||
defer ts.Close() | ||
|
||
client := NewClient() | ||
req := client.Request() | ||
req.SetRequestURI(ts.URL).SetMethod("GET") | ||
|
||
err := client.SendRequest() | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
if client.res.StatusCode != http.StatusOK { | ||
t.Fatalf("expected status code 200, got %d", client.res.StatusCode) | ||
} | ||
} | ||
|
||
func TestClient_SendRequest_MissingURI(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
req.SetMethod("GET") | ||
|
||
err := client.SendRequest() | ||
if !errors.Is(err, ErrURIRequired) { | ||
t.Fatalf("expected ErrURIRequired, got %v", err) | ||
} | ||
} | ||
|
||
func TestClient_SendRequest_MissingMethod(t *testing.T) { | ||
client := NewClient() | ||
req := client.Request() | ||
req.SetRequestURI("https://example.com") | ||
|
||
err := client.SendRequest() | ||
if !errors.Is(err, ErrMethodRequired) { | ||
t.Fatalf("expected ErrMethodRequired, got %v", err) | ||
} | ||
} | ||
|
||
func TestClient_ReadResponse(t *testing.T) { | ||
// Setup a test server | ||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
w.WriteHeader(http.StatusOK) | ||
w.Write([]byte("response body")) | ||
})) | ||
defer ts.Close() | ||
|
||
client := NewClient() | ||
req := client.Request() | ||
req.SetRequestURI(ts.URL).SetMethod("GET") | ||
|
||
if err := client.SendRequest(); err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
|
||
code, body, err := client.ReadResponse() | ||
if err != nil { | ||
t.Fatalf("expected no error, got %v", err) | ||
} | ||
if code != http.StatusOK { | ||
t.Fatalf("expected status code 200, got %d", code) | ||
} | ||
if string(body) != "response body" { | ||
t.Fatalf("expected body 'response body', got %s", body) | ||
} | ||
} | ||
|
||
func TestClient_ReadResponse_NoResponse(t *testing.T) { | ||
client := NewClient() | ||
|
||
_, _, err := client.ReadResponse() | ||
if !errors.Is(err, ErrResponseIsNil) { | ||
t.Fatalf("expected ErrResponseIsNil, got %v", err) | ||
} | ||
} |
Oops, something went wrong.