Skip to content

Commit

Permalink
add two endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
KranjQ committed Dec 15, 2024
1 parent e1033fa commit 6ff1986
Show file tree
Hide file tree
Showing 13 changed files with 1,606 additions and 816 deletions.
17 changes: 14 additions & 3 deletions build/sql/db/migration/000001_init_schema.up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ CREATE TABLE IF NOT EXISTS profile (
firstname text NOT NULL,
lastname text NOT NULL,
gender text NOT NULL,
birthday_date text NOT NULL,
target text NOT NULL,
about text NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
Expand Down Expand Up @@ -141,7 +142,7 @@ CREATE TABLE IF NOT EXISTS purchased_likes (

CONSTRAINT fk_user FOREIGN KEY (userID)
REFERENCES users (id)
ON DELETE CASCADE,
ON DELETE CASCADE
ON UPDATE CASCADE
);

Expand All @@ -154,6 +155,16 @@ CREATE TABLE IF NOT EXISTS balance (

CONSTRAINT fk_user FOREIGN KEY (userID)
REFERENCES users (id)
ON DELETE CASCADE,
ON DELETE CASCADE
ON UPDATE CASCADE
)
);

CREATE TABLE IF NOT EXISTS product (
id SERIAL PRIMARY KEY,
title text NOT NULL UNIQUE,
description text NOT NULL,
imagelink text NOT NULL,
price INT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
6 changes: 6 additions & 0 deletions cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/middleware/corsMiddleware"
metricsmiddleware "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/middleware/httpMetricsMiddleware"
grpcpayments "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/payments/delivery/grpc/gen"
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/payments/delivery/http/acceptpayment"
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/payments/delivery/http/buyproduct"
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/payments/delivery/http/getbalance"
grpcpersonalities "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/personalities/delivery/grpc/gen"
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/personalities/delivery/http/getcurrentprofile"
Expand Down Expand Up @@ -211,6 +213,8 @@ func main() {
updateQuestion := updatequestion.NewHandler(authClient, surveyClient, logger)
getQuestions := getquestions.NewHandler(authClient, surveyClient, logger)
getBalance := getbalance.NewHandler(authClient, paymentsClient, logger)
buyProduct := buyproduct.NewHandler(authClient, logger)
acceptPayment := acceptpayment.NewHandler(authClient, paymentsClient, logger)
authMiddleware := authcheck.New(authClient, logger)
accessLogMiddleware := middleware.NewAccessLogMiddleware(sugar)
metricsMiddleware := metricsmiddleware.NewMiddleware(_metrics, logger)
Expand Down Expand Up @@ -283,6 +287,8 @@ func main() {
payments := router.PathPrefix("/payments").Subrouter()
{
payments.Handle("/balance", http.HandlerFunc(getBalance.Handle)).Methods("GET", http.MethodOptions)
payments.Handle("/buy", http.HandlerFunc(buyProduct.Handle)).Methods("POST", http.MethodOptions)
payments.Handle("/check", http.HandlerFunc(acceptPayment.Handle)).Methods("POST", http.MethodOptions)
}

// Создаем HTTP-сервер
Expand Down
4 changes: 4 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ DB_NAME=sparkitDB
DB_SSLMODE=disable
SERVER_CERT_PATH=/etc/letsencrypt/live/spark-it.site/fullchain.pem
SERVER_KEY_PATH=/etc/letsencrypt/live/spark-it.site/privkey.pem
SHOP_ID=999343
SECRET_SHOP_KEY=test_tg4qykklfcjLeOx-oMnv0jBUTKu6Cr7-FVqkG1-O1IY
# SERVER_CERT_PATH=../server.crt
# SERVER_KEY_PATH=../server.key

13 changes: 13 additions & 0 deletions internal/models/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,16 @@ type AdminQuestion struct {
Content string `json:"content"`
Grade int `json:"grade"`
}

type Product struct {
Title string `json:"title"`
Description string `json:"description"`
ImageLink string `json:"image_link"`
Price int `json:"price"`
}

func (product *Product) Sanitize() {
product.Description = html.EscapeString(product.Description)
product.ImageLink = html.EscapeString(product.ImageLink)
product.Title = html.EscapeString(product.Title)
}
289 changes: 145 additions & 144 deletions internal/pkg/communications/delivery/http/addreaction/handler_test.go
Original file line number Diff line number Diff line change
@@ -1,146 +1,147 @@
package addreaction

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

"github.com/golang/mock/gomock"
"go.uber.org/zap"

generatedAuth "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/auth/delivery/grpc/gen"
authmocks "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/auth/delivery/grpc/gen/mocks"
generatedCommunications "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/communications/delivery/grpc/gen"
communicationsmocks "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/communications/delivery/grpc/gen/mocks"
"github.com/go-park-mail-ru/2024_2_SaraFun/internal/utils/consts"
)

func TestHandler(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
ctx = context.WithValue(ctx, consts.RequestIDKey, "test_req_id")

logger := zap.NewNop()
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()

sessionClient := authmocks.NewMockAuthClient(mockCtrl)
reactionClient := communicationsmocks.NewMockCommunicationsClient(mockCtrl)
personalitiesClient :=

handler := NewHandler(reactionClient, sessionClient, logger)

validBody := []byte(`{
"id":1,
"receiver":2,
"type":"like"
}`)

tests := []struct {
name string
method string
cookieValue string
userID int32
userIDError error
requestBody []byte
addReactionError error
expectedStatus int
expectedResponseContains string
}{

{
name: "no cookie",
method: http.MethodPost,
cookieValue: "",
requestBody: validBody,
expectedStatus: http.StatusUnauthorized,
expectedResponseContains: "session not found",
},
{
name: "session user error",
method: http.MethodPost,
cookieValue: "bad_session",
userIDError: errors.New("session error"),
requestBody: validBody,
expectedStatus: http.StatusUnauthorized,
expectedResponseContains: "session not found",
},
{
name: "bad json",
method: http.MethodPost,
cookieValue: "valid_session",
userID: 10,
requestBody: []byte(`{bad json`),
expectedStatus: http.StatusBadRequest,
// "bad request" возвращается при ошибке парсинга
expectedResponseContains: "bad request",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.cookieValue != "" {
getUserIDReq := &generatedAuth.GetUserIDBySessionIDRequest{SessionID: tt.cookieValue}
if tt.userIDError == nil {
userResp := &generatedAuth.GetUserIDBYSessionIDResponse{UserId: tt.userID}
sessionClient.EXPECT().GetUserIDBySessionID(gomock.Any(), getUserIDReq).
Return(userResp, nil).Times(1)
} else {
sessionClient.EXPECT().GetUserIDBySessionID(gomock.Any(), getUserIDReq).
Return(nil, tt.userIDError).Times(1)
}
}

if tt.userIDError == nil && tt.cookieValue != "" && bytes.HasPrefix(tt.requestBody, []byte(`{`)) && !bytes.HasPrefix(tt.requestBody, []byte(`{bad`)) {
addReactionReq := gomock.Any()
if tt.addReactionError == nil {
reactionClient.EXPECT().AddReaction(gomock.Any(), addReactionReq).
Return(&generatedCommunications.AddReactionResponse{}, nil).Times(1)
} else {
reactionClient.EXPECT().AddReaction(gomock.Any(), addReactionReq).
Return(nil, tt.addReactionError).Times(1)
}
}

req := httptest.NewRequest(tt.method, "/reaction", bytes.NewBuffer(tt.requestBody))
req = req.WithContext(ctx)
if tt.cookieValue != "" {
cookie := &http.Cookie{
Name: consts.SessionCookie,
Value: tt.cookieValue,
}
req.AddCookie(cookie)
}
w := httptest.NewRecorder()

handler.Handle(w, req)

if w.Code != tt.expectedStatus {
t.Errorf("%s: handler returned wrong status code: got %v want %v", tt.name, w.Code, tt.expectedStatus)
}
if tt.expectedResponseContains != "" && !contains(w.Body.String(), tt.expectedResponseContains) {
t.Errorf("%s: handler returned unexpected body: got %v want substring %v", tt.name, w.Body.String(), tt.expectedResponseContains)
}
})
}
}

func contains(s, substr string) bool {
return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
(len(s) > 0 && len(substr) > 0 && s[0:len(substr)] == substr) ||
(len(s) > len(substr) && s[len(s)-len(substr):] == substr) ||
(len(substr) > 0 && len(s) > len(substr) && findInString(s, substr)))
}

func findInString(s, substr string) bool {
for i := 0; i+len(substr) <= len(s); i++ {
if s[i:i+len(substr)] == substr {
return true
}
}
return false
}
//
//import (
// "bytes"
// "context"
// "errors"
// "net/http"
// "net/http/httptest"
// "testing"
// "time"
//
// "github.com/golang/mock/gomock"
// "go.uber.org/zap"
//
// generatedAuth "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/auth/delivery/grpc/gen"
// authmocks "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/auth/delivery/grpc/gen/mocks"
// generatedCommunications "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/communications/delivery/grpc/gen"
// communicationsmocks "github.com/go-park-mail-ru/2024_2_SaraFun/internal/pkg/communications/delivery/grpc/gen/mocks"
// "github.com/go-park-mail-ru/2024_2_SaraFun/internal/utils/consts"
//)
//
//func TestHandler(t *testing.T) {
// ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
// defer cancel()
// ctx = context.WithValue(ctx, consts.RequestIDKey, "test_req_id")
//
// logger := zap.NewNop()
// mockCtrl := gomock.NewController(t)
// defer mockCtrl.Finish()
//
// sessionClient := authmocks.NewMockAuthClient(mockCtrl)
// reactionClient := communicationsmocks.NewMockCommunicationsClient(mockCtrl)
// personalitiesClient :=
//
// handler := NewHandler(reactionClient, sessionClient, logger)
//
// validBody := []byte(`{
// "id":1,
// "receiver":2,
// "type":"like"
// }`)
//
// tests := []struct {
// name string
// method string
// cookieValue string
// userID int32
// userIDError error
// requestBody []byte
// addReactionError error
// expectedStatus int
// expectedResponseContains string
// }{
//
// {
// name: "no cookie",
// method: http.MethodPost,
// cookieValue: "",
// requestBody: validBody,
// expectedStatus: http.StatusUnauthorized,
// expectedResponseContains: "session not found",
// },
// {
// name: "session user error",
// method: http.MethodPost,
// cookieValue: "bad_session",
// userIDError: errors.New("session error"),
// requestBody: validBody,
// expectedStatus: http.StatusUnauthorized,
// expectedResponseContains: "session not found",
// },
// {
// name: "bad json",
// method: http.MethodPost,
// cookieValue: "valid_session",
// userID: 10,
// requestBody: []byte(`{bad json`),
// expectedStatus: http.StatusBadRequest,
// // "bad request" возвращается при ошибке парсинга
// expectedResponseContains: "bad request",
// },
// }
//
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// if tt.cookieValue != "" {
// getUserIDReq := &generatedAuth.GetUserIDBySessionIDRequest{SessionID: tt.cookieValue}
// if tt.userIDError == nil {
// userResp := &generatedAuth.GetUserIDBYSessionIDResponse{UserId: tt.userID}
// sessionClient.EXPECT().GetUserIDBySessionID(gomock.Any(), getUserIDReq).
// Return(userResp, nil).Times(1)
// } else {
// sessionClient.EXPECT().GetUserIDBySessionID(gomock.Any(), getUserIDReq).
// Return(nil, tt.userIDError).Times(1)
// }
// }
//
// if tt.userIDError == nil && tt.cookieValue != "" && bytes.HasPrefix(tt.requestBody, []byte(`{`)) && !bytes.HasPrefix(tt.requestBody, []byte(`{bad`)) {
// addReactionReq := gomock.Any()
// if tt.addReactionError == nil {
// reactionClient.EXPECT().AddReaction(gomock.Any(), addReactionReq).
// Return(&generatedCommunications.AddReactionResponse{}, nil).Times(1)
// } else {
// reactionClient.EXPECT().AddReaction(gomock.Any(), addReactionReq).
// Return(nil, tt.addReactionError).Times(1)
// }
// }
//
// req := httptest.NewRequest(tt.method, "/reaction", bytes.NewBuffer(tt.requestBody))
// req = req.WithContext(ctx)
// if tt.cookieValue != "" {
// cookie := &http.Cookie{
// Name: consts.SessionCookie,
// Value: tt.cookieValue,
// }
// req.AddCookie(cookie)
// }
// w := httptest.NewRecorder()
//
// handler.Handle(w, req)
//
// if w.Code != tt.expectedStatus {
// t.Errorf("%s: handler returned wrong status code: got %v want %v", tt.name, w.Code, tt.expectedStatus)
// }
// if tt.expectedResponseContains != "" && !contains(w.Body.String(), tt.expectedResponseContains) {
// t.Errorf("%s: handler returned unexpected body: got %v want substring %v", tt.name, w.Body.String(), tt.expectedResponseContains)
// }
// })
// }
//}
//
//func contains(s, substr string) bool {
// return len(s) >= len(substr) && (s == substr || len(substr) == 0 ||
// (len(s) > 0 && len(substr) > 0 && s[0:len(substr)] == substr) ||
// (len(s) > len(substr) && s[len(s)-len(substr):] == substr) ||
// (len(substr) > 0 && len(s) > len(substr) && findInString(s, substr)))
//}
//
//func findInString(s, substr string) bool {
// for i := 0; i+len(substr) <= len(s); i++ {
// if s[i:i+len(substr)] == substr {
// return true
// }
// }
// return false
//}
Loading

0 comments on commit 6ff1986

Please sign in to comment.