Skip to content

Commit

Permalink
⚡️ Implemented /criteria/{criteria_id}/enqueue/v1 endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
lhbelfanti committed Sep 10, 2024
1 parent eaa05f1 commit 2faaf83
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ APP_INTERNAL_PORT=4000 # Container port
DB_NAME=ahbcc
DB_USER=ahbcc_user
DB_PASS=ahbcc_password
DB_PORT=5432
DB_PORT=5432

# External APIs URLs
ENQUEUE_CRITERIA_API_URL=http://localhost:5100
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ DB_NAME=<Database name>
DB_USER=<Database username>
DB_PASS=<Database password>
DB_PORT=<Database port>
# External APIs URLs
ENQUEUE_CRITERIA_API_URL=<Domain of the application with the endpoint /criteria/enqueue/v1> --> Example: the URL to the GoXCrap API
```

Replace the `< ... >` by the correct value. For example: `DB_NAME=<Database name>` --> `DB_NAME=ahbcc`.
9 changes: 9 additions & 0 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ import (

"ahbcc/cmd/api/migrations"
"ahbcc/cmd/api/ping"
"ahbcc/cmd/api/search/criteria"
"ahbcc/cmd/api/tweets"
"ahbcc/cmd/api/tweets/quotes"
"ahbcc/internal/database"
_http "ahbcc/internal/http"
"ahbcc/internal/log"
"ahbcc/internal/scrapper"
"ahbcc/internal/setup"
)

Expand All @@ -36,6 +39,8 @@ func main() {

log.NewCustomLogger(os.Stdout, logLevel)

httpClient := _http.NewClient()

// Database
pg := setup.Init(database.InitPostgres())
defer pg.Close()
Expand All @@ -49,13 +54,17 @@ func main() {
insertSingleQuote := quotes.MakeInsertSingle(db)
deleteOrphanQuotes := quotes.MakeDeleteOrphans(db)
insertTweets := tweets.MakeInsert(db, insertSingleQuote, deleteOrphanQuotes)
selectCriteriaByID := criteria.MakeSelectByID(db)
scrapperEnqueueCriteria := scrapper.MakeEnqueueCriteria(httpClient, os.Getenv("ENQUEUE_CRITERIA_API_URL"))
enqueueCriteria := criteria.MakeEnqueue(selectCriteriaByID, scrapperEnqueueCriteria)

/* --- Router --- */
log.Info(ctx, "Initializing router...")
router := http.NewServeMux()
router.HandleFunc("GET /ping/v1", ping.HandlerV1())
router.HandleFunc("POST /migrations/run/v1", migrations.RunHandlerV1(runMigrations))
router.HandleFunc("POST /tweets/v1", tweets.InsertHandlerV1(insertTweets))
router.HandleFunc("POST /criteria/{criteria_id}/enqueue/v1", criteria.EnqueueHandlerV1(enqueueCriteria))
log.Info(ctx, "Router initialized!")

/* --- Server --- */
Expand Down
34 changes: 34 additions & 0 deletions cmd/api/search/criteria/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package criteria

import (
"net/http"
"strconv"

"ahbcc/internal/log"
)

// EnqueueHandlerV1 HTTP Handler of the endpoint /criteria/enqueue/v1
func EnqueueHandlerV1(enqueueCriteria Enqueue) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()

criteriaIDParam := r.PathValue("criteria_id")
criteriaID, err := strconv.Atoi(criteriaIDParam)
if err != nil {
log.Error(ctx, err.Error())
http.Error(w, InvalidURLParameter, http.StatusBadRequest)
return
}

err = enqueueCriteria(ctx, criteriaID)
if err != nil {
log.Error(ctx, err.Error())
http.Error(w, FailedToEnqueueCriteria, http.StatusInternalServerError)
return
}

log.Info(ctx, "Criteria successfully sent to enqueue")
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("Criteria successfully sent to enqueue"))
}
}
80 changes: 80 additions & 0 deletions cmd/api/search/criteria/handler_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package criteria_test

import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"

"ahbcc/cmd/api/search/criteria"
)

func TestEnqueueHandlerV1_success(t *testing.T) {
mockEnqueueCriteria := criteria.MockEnqueue(nil)

mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/enqueue/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "1")

handlerV1 := criteria.EnqueueHandlerV1(mockEnqueueCriteria)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusOK
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestEnqueueHandlerV1_failedWhenTheURLParamIsEmpty(t *testing.T) {
mockEnqueueCriteria := criteria.MockEnqueue(nil)

mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/enqueue/v1", http.NoBody)

handlerV1 := criteria.EnqueueHandlerV1(mockEnqueueCriteria)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusBadRequest
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestEnqueueHandlerV1_failedWhenTheURLParamCannotBeParsed(t *testing.T) {
mockEnqueueCriteria := criteria.MockEnqueue(nil)

mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/enqueue/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "error")

handlerV1 := criteria.EnqueueHandlerV1(mockEnqueueCriteria)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusBadRequest
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

func TestEnqueueHandlerV1_failsWhenEnqueueCriteriaThrowsError(t *testing.T) {
mockEnqueueCriteria := criteria.MockEnqueue(errors.New("failed while executing enqueue criteria"))

mockResponseWriter := httptest.NewRecorder()
mockRequest, _ := http.NewRequestWithContext(context.Background(), http.MethodPost, "/criteria/{criteria_id}/enqueue/v1", http.NoBody)
mockRequest.SetPathValue("criteria_id", "1")

handlerV1 := criteria.EnqueueHandlerV1(mockEnqueueCriteria)

handlerV1(mockResponseWriter, mockRequest)

want := http.StatusInternalServerError
got := mockResponseWriter.Result().StatusCode

assert.Equal(t, want, got)
}

0 comments on commit 2faaf83

Please sign in to comment.