mirror of
https://github.com/vcscsvcscs/GenerationsHeritage.git
synced 2025-08-13 06:19:05 +02:00
add comments
This commit is contained in:
94
apps/db-adapter/integration-tests/comment.go
Normal file
94
apps/db-adapter/integration-tests/comment.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package integration_tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
)
|
||||
|
||||
//go:embed payloads/comment.json
|
||||
var comment []byte
|
||||
|
||||
func CommentOnPersonTest(dbAdapterUri string, client *http.Client) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
url := dbAdapterUri + "/comment/8"
|
||||
|
||||
req, err := http.NewRequestWithContext(t.Context(), http.MethodPost, url, bytes.NewBuffer(comment))
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("X-User-ID", "6")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func GetCommentsOnPersonTest(dbAdapterUri string, client *http.Client) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
url := dbAdapterUri + "/comment/8"
|
||||
|
||||
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, url, http.NoBody)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("X-User-ID", "6")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
require.NoError(t, err)
|
||||
defer resp.Body.Close()
|
||||
|
||||
require.Equal(t, http.StatusOK, resp.StatusCode)
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(body), "StartElementId")
|
||||
}
|
||||
}
|
||||
|
||||
//go:embed payloads/edit_comment.json
|
||||
var edit_comment []byte
|
||||
|
||||
func PatchCommentOnPersonTest(dbAdapterUri string, client *http.Client) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
patchURL := dbAdapterUri + "/comment/8"
|
||||
|
||||
patchReq, err := http.NewRequestWithContext(t.Context(), http.MethodPatch, patchURL, bytes.NewBuffer(edit_comment))
|
||||
require.NoError(t, err)
|
||||
patchReq.Header.Set("Content-Type", "application/json")
|
||||
patchReq.Header.Set("X-User-ID", "6")
|
||||
|
||||
patchResp, err := client.Do(patchReq)
|
||||
require.NoError(t, err)
|
||||
defer patchResp.Body.Close()
|
||||
|
||||
require.Equal(t, http.StatusOK, patchResp.StatusCode)
|
||||
|
||||
var responseBody api.Messages
|
||||
err = json.NewDecoder(patchResp.Body).Decode(&responseBody)
|
||||
require.NoError(t, err)
|
||||
require.NotEmpty(t, responseBody.Comments)
|
||||
require.Len(t, *responseBody.Comments, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteCommentOnPersonTest(dbAdapterUri string, client *http.Client) func(t *testing.T) {
|
||||
return func(t *testing.T) {
|
||||
deleteURL := dbAdapterUri + "/comment/8"
|
||||
deleteReq, err := http.NewRequestWithContext(t.Context(), http.MethodDelete, deleteURL, http.NoBody)
|
||||
require.NoError(t, err)
|
||||
deleteReq.Header.Set("X-User-ID", "6")
|
||||
|
||||
deleteResp, err := client.Do(deleteReq)
|
||||
require.NoError(t, err)
|
||||
defer deleteResp.Body.Close()
|
||||
|
||||
require.Equal(t, http.StatusOK, deleteResp.StatusCode)
|
||||
}
|
||||
}
|
5
apps/db-adapter/integration-tests/payloads/comment.json
Normal file
5
apps/db-adapter/integration-tests/payloads/comment.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"message": "Test comment",
|
||||
"created_at": "2023-10-01T12:00:00Z",
|
||||
"updated_at": "2023-10-01T12:00:00Z"
|
||||
}
|
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"message": "Test comment **edited**",
|
||||
"created_at": "2023-10-01T12:00:00Z",
|
||||
"updated_at": "2023-11-01T12:00:00Z"
|
||||
}
|
@@ -14,7 +14,7 @@ func CouldSeePersonsProfile(ctx context.Context, session neo4j.SessionWithContex
|
||||
return nil
|
||||
}
|
||||
|
||||
res, err := session.ExecuteRead(ctx, memgraph.GetFamilyTreeById(ctx, xUserID))
|
||||
res, err := session.ExecuteRead(ctx, memgraph.GetFamilyTreeWithSpousesById(ctx, xUserID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
120
apps/db-adapter/internal/api/comment.go
Normal file
120
apps/db-adapter/internal/api/comment.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/api/auth"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
)
|
||||
|
||||
func (srv *server) CommentOnPerson(c *gin.Context, id int, params api.CommentOnPersonParams) { //nolint:dupl,lll // This just does not worth abstracting anymore
|
||||
var comment api.Message
|
||||
if err := c.ShouldBindJSON(&comment); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer acancel()
|
||||
if err := auth.CouldSeePersonsProfile(actx, session, id, params.XUserID); err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"msg": fmt.Sprint("User does not have access to this person", err.Error())})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
res, err := session.ExecuteWrite(qctx, memgraph.UpsertCommentOnProfile(
|
||||
qctx, params.XUserID, id, &comment,
|
||||
))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
||||
|
||||
func (srv *server) EditComment(c *gin.Context, id int, params api.EditCommentParams) { //nolint:dupl,lll // This just does not worth abstracting anymore
|
||||
var comment api.Message
|
||||
if err := c.ShouldBindJSON(&comment); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer acancel()
|
||||
if err := auth.CouldSeePersonsProfile(actx, session, id, params.XUserID); err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"msg": fmt.Sprint("User does not have access to this person", err.Error())})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
res, err := session.ExecuteWrite(qctx, memgraph.UpsertCommentOnProfile(
|
||||
qctx, params.XUserID, id, &comment,
|
||||
))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
||||
|
||||
func (srv *server) DeleteCommentOnPerson(c *gin.Context, id int, params api.DeleteCommentOnPersonParams) {
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
_, err := session.ExecuteWrite(qctx, memgraph.DeleteComment(
|
||||
qctx, params.XUserID, id,
|
||||
))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"msg": "Comment deleted successfully"})
|
||||
}
|
||||
|
||||
func (srv *server) GetCommentsOnPerson(c *gin.Context, id int, params api.GetCommentsOnPersonParams) { //nolint:dupl,lll // This just does not worth abstracting anymore
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
actx, acancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer acancel()
|
||||
if err := auth.CouldSeePersonsProfile(actx, session, id, params.XUserID); err != nil {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{"msg": fmt.Sprint("User does not have access to this person", err.Error())})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
qctx, qCancel := context.WithTimeout(c.Request.Context(), srv.dbOpTimeout)
|
||||
defer qCancel()
|
||||
res, err := session.ExecuteRead(qctx, memgraph.GetCommentsOnProfile(qctx, id))
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"msg": err.Error()})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, res)
|
||||
}
|
164
apps/db-adapter/internal/api/comment_test.go
Normal file
164
apps/db-adapter/internal/api/comment_test.go
Normal file
@@ -0,0 +1,164 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
memgraphMock "github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
)
|
||||
|
||||
func mockServer(writeErr, authErr error, writeResult any) *server {
|
||||
mockSession := new(memgraphMock.SessionWithContext)
|
||||
mockDriver := new(memgraphMock.DriverWithContext)
|
||||
mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession)
|
||||
|
||||
if authErr != nil {
|
||||
mockSession.On("ExecuteRead", mock.Anything, mock.Anything, mock.Anything).Return(nil, authErr)
|
||||
} else {
|
||||
mockSession.On("ExecuteRead", mock.Anything, mock.Anything, mock.Anything).Return(nil, nil)
|
||||
}
|
||||
|
||||
if writeErr != nil {
|
||||
mockSession.On("ExecuteWrite", mock.Anything, mock.Anything, mock.Anything).Return(nil, writeErr)
|
||||
} else {
|
||||
mockSession.On("ExecuteWrite", mock.Anything, mock.Anything, mock.Anything).Return(writeResult, nil)
|
||||
}
|
||||
|
||||
mockSession.On("Close", mock.Anything).Return(nil)
|
||||
|
||||
return &server{
|
||||
db: mockDriver,
|
||||
dbOpTimeout: 2 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func requestWithBody(method, url, body string) (*gin.Context, *httptest.ResponseRecorder) { //nolint:unparam // could be fixed in the future
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequestWithContext(context.Background(), method, url, bytes.NewBufferString(body))
|
||||
c.Request.Header.Set("Content-Type", "application/json")
|
||||
return c, w
|
||||
}
|
||||
|
||||
func TestCommentOnPerson(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
srv := mockServer(nil, nil, map[string]any{"ok": true})
|
||||
c, w := requestWithBody(http.MethodPost, "/comment", `{"text": "Hello"}`)
|
||||
params := api.CommentOnPersonParams{XUserID: 1}
|
||||
|
||||
srv.CommentOnPerson(c, 123, params)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "ok")
|
||||
})
|
||||
|
||||
t.Run("Unauthorized", func(t *testing.T) {
|
||||
srv := mockServer(nil, errors.New("unauthorized"), nil)
|
||||
c, w := requestWithBody(http.MethodPost, "/comment", `{"text": "Hi"}`)
|
||||
params := api.CommentOnPersonParams{XUserID: 1}
|
||||
|
||||
srv.CommentOnPerson(c, 456, params)
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "unauthorized")
|
||||
})
|
||||
|
||||
t.Run("Database error", func(t *testing.T) {
|
||||
srv := mockServer(errors.New("db error"), nil, nil)
|
||||
c, w := requestWithBody(http.MethodPost, "/comment", `{"text": "Oops"}`)
|
||||
params := api.CommentOnPersonParams{XUserID: 2}
|
||||
|
||||
srv.CommentOnPerson(c, 789, params)
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "db error")
|
||||
})
|
||||
}
|
||||
|
||||
func TestEditComment(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
srv := mockServer(nil, nil, map[string]any{"updated": true})
|
||||
c, w := requestWithBody(http.MethodPut, "/comment", `{"text": "Updated text"}`)
|
||||
params := api.EditCommentParams{XUserID: 4}
|
||||
|
||||
srv.EditComment(c, 101, params)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "updated")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteCommentOnPerson(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
srv := mockServer(nil, nil, nil)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/comment", http.NoBody)
|
||||
|
||||
params := api.DeleteCommentOnPersonParams{XUserID: 5}
|
||||
srv.DeleteCommentOnPerson(c, 202, params)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "Comment deleted")
|
||||
})
|
||||
|
||||
t.Run("DB error", func(t *testing.T) {
|
||||
srv := mockServer(errors.New("delete error"), nil, nil)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodDelete, "/comment", http.NoBody)
|
||||
|
||||
params := api.DeleteCommentOnPersonParams{XUserID: 6}
|
||||
srv.DeleteCommentOnPerson(c, 303, params)
|
||||
|
||||
assert.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "delete error")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetCommentsOnPerson(t *testing.T) {
|
||||
t.Run("Success", func(t *testing.T) {
|
||||
mockSession := new(memgraphMock.SessionWithContext)
|
||||
mockDriver := new(memgraphMock.DriverWithContext)
|
||||
mockDriver.On("NewSession", mock.Anything, mock.Anything).Return(mockSession)
|
||||
mockSession.On("ExecuteRead", mock.Anything, mock.Anything, mock.Anything).Return([]string{"Comment 1"}, nil)
|
||||
mockSession.On("Close", mock.Anything).Return(nil)
|
||||
|
||||
srv := &server{
|
||||
db: mockDriver,
|
||||
dbOpTimeout: 2 * time.Second,
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/comment", http.NoBody)
|
||||
|
||||
params := api.GetCommentsOnPersonParams{XUserID: 7}
|
||||
srv.GetCommentsOnPerson(c, 404, params)
|
||||
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "Comment 1")
|
||||
})
|
||||
|
||||
t.Run("Unauthorized", func(t *testing.T) {
|
||||
srv := mockServer(nil, errors.New("access denied"), nil)
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(w)
|
||||
c.Request = httptest.NewRequest(http.MethodGet, "/comment", http.NoBody)
|
||||
|
||||
params := api.GetCommentsOnPersonParams{XUserID: 8}
|
||||
srv.GetCommentsOnPerson(c, 505, params)
|
||||
|
||||
assert.Equal(t, http.StatusUnauthorized, w.Code)
|
||||
assert.Contains(t, w.Body.String(), "access denied")
|
||||
})
|
||||
}
|
@@ -87,7 +87,7 @@ func (srv *server) CreatePerson(c *gin.Context, params api.CreatePersonParams) {
|
||||
c.JSON(http.StatusOK, createdPerson)
|
||||
}
|
||||
|
||||
func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) {
|
||||
func (srv *server) GetPersonById(c *gin.Context, id int, params api.GetPersonByIdParams) { //nolint:dupl,lll // This just does not worth abstracting anymore
|
||||
session := srv.createSessionWithTimeout(c.Request.Context())
|
||||
defer closeSession(c.Request.Context(), srv.logger, session, srv.dbOpTimeout)
|
||||
|
||||
|
66
apps/db-adapter/internal/memgraph/comments.go
Normal file
66
apps/db-adapter/internal/memgraph/comments.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package memgraph
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
)
|
||||
|
||||
func UpsertCommentOnProfile(ctx context.Context, commenter, profile int, comment *api.Message) neo4j.ManagedTransactionWork {
|
||||
convertedComment := StructToMap(comment)
|
||||
return func(tx neo4j.ManagedTransaction) (any, error) {
|
||||
result, err := tx.Run(ctx, CommentCypherQuery, map[string]any{
|
||||
"id1": commenter,
|
||||
"id2": profile,
|
||||
"comment": convertedComment,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record, err := result.Single(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record.AsMap(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetCommentsOnProfile(ctx context.Context, profile int) neo4j.ManagedTransactionWork {
|
||||
return func(tx neo4j.ManagedTransaction) (any, error) {
|
||||
result, err := tx.Run(ctx, CommentsOnProfileCypherQuery, map[string]any{
|
||||
"id": profile,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
record, err := result.Single(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return record.AsMap(), nil
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteComment(ctx context.Context, commenter, profile int) neo4j.ManagedTransactionWork {
|
||||
return func(tx neo4j.ManagedTransaction) (any, error) {
|
||||
result, err := tx.Run(ctx, DeleteCommentCypherQuery, map[string]any{
|
||||
"id1": commenter,
|
||||
"id2": profile,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if result.Peek(ctx) {
|
||||
return nil, fmt.Errorf("there was a returned value, when deleting admin but there should be none")
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
}
|
197
apps/db-adapter/internal/memgraph/comments_test.go
Normal file
197
apps/db-adapter/internal/memgraph/comments_test.go
Normal file
@@ -0,0 +1,197 @@
|
||||
package memgraph
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/neo4j/neo4j-go-driver/v5/neo4j"
|
||||
mmock "github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/internal/memgraph/mock"
|
||||
"github.com/vcscsvcscs/GenerationsHeritage/apps/db-adapter/pkg/api"
|
||||
)
|
||||
|
||||
func TestUpsertCommentOnProfile(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
comment := &api.Message{Message: api.StringPtr("Hello!")}
|
||||
commentMap := StructToMap(comment)
|
||||
|
||||
testCases := []struct {
|
||||
expectedResult map[string]any
|
||||
mockTxSetup func() *mock.Transaction
|
||||
expectedError error
|
||||
name string
|
||||
}{
|
||||
{
|
||||
name: "Successful case",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockRecord := &neo4j.Record{Values: []any{"val"}, Keys: []string{"out"}}
|
||||
mockResult.On("Single", ctx).Return(mockRecord, nil)
|
||||
mockTx.On("Run", ctx, CommentCypherQuery, map[string]any{"id1": 1, "id2": 2, "comment": commentMap}).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: map[string]any{"out": "val"},
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Run error",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockTx.On("Run", ctx, CommentCypherQuery, mmock.Anything).Return(nil, errors.New("run error"))
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: nil,
|
||||
expectedError: errors.New("run error"),
|
||||
},
|
||||
{
|
||||
name: "Single error",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockResult.On("Single", ctx).Return(nil, errors.New("single error"))
|
||||
mockTx.On("Run", ctx, CommentCypherQuery, mmock.Anything).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: nil,
|
||||
expectedError: errors.New("single error"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
work := UpsertCommentOnProfile(ctx, 1, 2, comment)
|
||||
result, err := work(tc.mockTxSetup())
|
||||
|
||||
if tc.expectedError != nil {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedResult, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCommentsOnProfile(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
testCases := []struct {
|
||||
expectedResult map[string]any
|
||||
mockTxSetup func() *mock.Transaction
|
||||
expectedError error
|
||||
name string
|
||||
}{
|
||||
{
|
||||
name: "Successful case",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockRecord := &neo4j.Record{Values: []any{"some"}, Keys: []string{"comments"}}
|
||||
mockResult.On("Single", ctx).Return(mockRecord, nil)
|
||||
mockTx.On("Run", ctx, CommentsOnProfileCypherQuery, map[string]any{"id": 2}).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: map[string]any{"comments": "some"},
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Run error",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockTx.On("Run", ctx, CommentsOnProfileCypherQuery, mmock.Anything).Return(nil, errors.New("run error"))
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: nil,
|
||||
expectedError: errors.New("run error"),
|
||||
},
|
||||
{
|
||||
name: "Single error",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockResult.On("Single", ctx).Return(nil, errors.New("single error"))
|
||||
mockTx.On("Run", ctx, CommentsOnProfileCypherQuery, mmock.Anything).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedResult: nil,
|
||||
expectedError: errors.New("single error"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
work := GetCommentsOnProfile(ctx, 2)
|
||||
result, err := work(tc.mockTxSetup())
|
||||
|
||||
if tc.expectedError != nil {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.expectedResult, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteComment(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
testCases := []struct {
|
||||
mockTxSetup func() *mock.Transaction
|
||||
expectedError error
|
||||
name string
|
||||
}{
|
||||
{
|
||||
name: "Successful deletion",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockResult.On("Peek", ctx).Return(false)
|
||||
mockTx.On("Run", ctx, DeleteCommentCypherQuery, map[string]any{"id1": 1, "id2": 2}).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
name: "Run error",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockTx.On("Run", ctx, DeleteCommentCypherQuery, mmock.Anything).Return(nil, errors.New("run error"))
|
||||
return mockTx
|
||||
},
|
||||
expectedError: errors.New("run error"),
|
||||
},
|
||||
{
|
||||
name: "Peek unexpected return",
|
||||
mockTxSetup: func() *mock.Transaction {
|
||||
mockTx := new(mock.Transaction)
|
||||
mockResult := new(mock.Result)
|
||||
mockResult.On("Peek", ctx).Return(true)
|
||||
mockTx.On("Run", ctx, DeleteCommentCypherQuery, mmock.Anything).Return(mockResult, nil)
|
||||
return mockTx
|
||||
},
|
||||
expectedError: errors.New("there was a returned value, when deleting admin but there should be none"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
work := DeleteComment(ctx, 1, 2)
|
||||
result, err := work(tc.mockTxSetup())
|
||||
|
||||
if tc.expectedError != nil {
|
||||
require.Error(t, err)
|
||||
require.Nil(t, result)
|
||||
require.EqualError(t, err, tc.expectedError.Error())
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Nil(t, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@@ -148,3 +148,22 @@ var GetBloodRelativesCypherQuery string
|
||||
//
|
||||
//go:embed queries/get_family_tree_with_spouses.cypher
|
||||
var GetFamilyTreeWithSpousesCypherQuery string
|
||||
|
||||
// Requires comment, id1 as commenter and id2 as profile that is commented on parameter.
|
||||
//
|
||||
// returns people, comments
|
||||
//
|
||||
//go:embed queries/comment.cypher
|
||||
var CommentCypherQuery string
|
||||
|
||||
// Requires id1 as commenter and id2 as profile that is commented on parameter.
|
||||
//
|
||||
//go:embed queries/delete_comment.cypher
|
||||
var DeleteCommentCypherQuery string
|
||||
|
||||
// Requires id1 as profile that is commented on parameter.
|
||||
//
|
||||
// returns comments, people
|
||||
//
|
||||
//go:embed queries/comments_on_profile.cypher
|
||||
var CommentsOnProfileCypherQuery string
|
||||
|
13
apps/db-adapter/internal/memgraph/queries/comment.cypher
Normal file
13
apps/db-adapter/internal/memgraph/queries/comment.cypher
Normal file
@@ -0,0 +1,13 @@
|
||||
MATCH (a:Person), (b:Person)
|
||||
WHERE id(a) = $id1 AND id(b) = $id2
|
||||
MERGE (a)-[r:Comment]->(b)
|
||||
SET r += $comment
|
||||
RETURN collect(r) as comments, collect({
|
||||
id: id(a),
|
||||
first_name: a.first_name,
|
||||
middle_name: a.middle_name,
|
||||
last_name: a.last_name,
|
||||
born: a.born,
|
||||
died: a.died,
|
||||
profile_picture: a.profile_picture
|
||||
}) as people;
|
@@ -0,0 +1,12 @@
|
||||
MATCH (b:Person)
|
||||
WHERE id(b) = $id
|
||||
MERGE (a)-[r:Comment]->(b)
|
||||
RETURN collect(r) as comments, collect({
|
||||
id: id(a),
|
||||
first_name: a.first_name,
|
||||
middle_name: a.middle_name,
|
||||
last_name: a.last_name,
|
||||
born: a.born,
|
||||
died: a.died,
|
||||
profile_picture: a.profile_picture
|
||||
}) as people;
|
@@ -0,0 +1,3 @@
|
||||
MATCH (a)-[r:Comment]->(b)
|
||||
WHERE id(a) = $id1 AND id(b) = $id2
|
||||
DELETE r;
|
@@ -120,5 +120,9 @@ func IntegrationTestFlow(dbAdapterURI string) func(t *testing.T) {
|
||||
t.Run("GetFamilyTreeWithSpousesByIdTest", integration_tests.GetFamilyTreeWithSpousesByIdTest(dbAdapterURI, client))
|
||||
t.Run("VerifyRelationships", integration_tests.UpdateRelationshipTest(dbAdapterURI, client))
|
||||
t.Run("DeleteRelationship", integration_tests.DeleteRelationshipTest(dbAdapterURI, client))
|
||||
t.Run("CreateComment", integration_tests.CommentOnPersonTest(dbAdapterURI, client))
|
||||
t.Run("GetCommentsOnPerson", integration_tests.GetCommentsOnPersonTest(dbAdapterURI, client))
|
||||
t.Run("PatchCommentOnPerson", integration_tests.PatchCommentOnPersonTest(dbAdapterURI, client))
|
||||
t.Run("DeleteCommentOnPerson", integration_tests.DeleteCommentOnPersonTest(dbAdapterURI, client))
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ package api
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/oapi-codegen/runtime"
|
||||
@@ -41,6 +42,16 @@ type Admin struct {
|
||||
Type *string `json:"Type,omitempty"`
|
||||
}
|
||||
|
||||
// Comment defines model for Comment.
|
||||
type Comment struct {
|
||||
End *int `json:"end"`
|
||||
Id *int `json:"id"`
|
||||
Label *string `json:"label"`
|
||||
Props *Message `json:"props,omitempty"`
|
||||
Start *int `json:"start"`
|
||||
Type *string `json:"type"`
|
||||
}
|
||||
|
||||
// FamilyRelationship defines model for FamilyRelationship.
|
||||
type FamilyRelationship struct {
|
||||
From *openapi_types.Date `json:"from"`
|
||||
@@ -73,6 +84,19 @@ type LikesProperties struct {
|
||||
LikeIt *bool `json:"like_it"`
|
||||
}
|
||||
|
||||
// Message defines model for Message.
|
||||
type Message struct {
|
||||
Edited *time.Time `json:"edited"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
SentAt *time.Time `json:"sent_at,omitempty"`
|
||||
}
|
||||
|
||||
// Messages defines model for Messages.
|
||||
type Messages struct {
|
||||
Comments *[]Comment `json:"comments,omitempty"`
|
||||
People *[]OptimizedPersonNode `json:"people,omitempty"`
|
||||
}
|
||||
|
||||
// OptimizedPersonNode defines model for OptimizedPersonNode.
|
||||
type OptimizedPersonNode struct {
|
||||
Born *openapi_types.Date `json:"born,omitempty"`
|
||||
@@ -150,15 +174,8 @@ type PersonProperties struct {
|
||||
} `json:"notes"`
|
||||
OccupationToDisplay *string `json:"occupation_to_display"`
|
||||
Occupations *[]string `json:"occupations"`
|
||||
OthersSaid *[]struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Relationship *string `json:"relationship,omitempty"`
|
||||
Url *string `json:"url"`
|
||||
} `json:"others_said"`
|
||||
Phone *string `json:"phone"`
|
||||
Photos *[]struct {
|
||||
Phone *string `json:"phone"`
|
||||
Photos *[]struct {
|
||||
Date *openapi_types.Date `json:"date,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
@@ -272,6 +289,26 @@ type CreateAdminRelationshipParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// DeleteCommentOnPersonParams defines parameters for DeleteCommentOnPerson.
|
||||
type DeleteCommentOnPersonParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// GetCommentsOnPersonParams defines parameters for GetCommentsOnPerson.
|
||||
type GetCommentsOnPersonParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// EditCommentParams defines parameters for EditComment.
|
||||
type EditCommentParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// CommentOnPersonParams defines parameters for CommentOnPerson.
|
||||
type CommentOnPersonParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// GetFamilyTreeByIdParams defines parameters for GetFamilyTreeById.
|
||||
type GetFamilyTreeByIdParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
@@ -408,6 +445,15 @@ type UpdateRelationshipParams struct {
|
||||
XUserID int `json:"X-User-ID"`
|
||||
}
|
||||
|
||||
// GetCommentsOnPersonJSONRequestBody defines body for GetCommentsOnPerson for application/json ContentType.
|
||||
type GetCommentsOnPersonJSONRequestBody = Message
|
||||
|
||||
// EditCommentJSONRequestBody defines body for EditComment for application/json ContentType.
|
||||
type EditCommentJSONRequestBody = Message
|
||||
|
||||
// CommentOnPersonJSONRequestBody defines body for CommentOnPerson for application/json ContentType.
|
||||
type CommentOnPersonJSONRequestBody = Message
|
||||
|
||||
// CreatePersonJSONRequestBody defines body for CreatePerson for application/json ContentType.
|
||||
type CreatePersonJSONRequestBody = PersonRegistration
|
||||
|
||||
@@ -449,6 +495,18 @@ type ServerInterface interface {
|
||||
// Create admin relationship between two persons
|
||||
// (POST /admin/{id1}/{id2})
|
||||
CreateAdminRelationship(c *gin.Context, id1 int, id2 int, params CreateAdminRelationshipParams)
|
||||
// Comment on person's profile by ID
|
||||
// (DELETE /comment/{id})
|
||||
DeleteCommentOnPerson(c *gin.Context, id int, params DeleteCommentOnPersonParams)
|
||||
// Get comments on person's profile by ID
|
||||
// (GET /comment/{id})
|
||||
GetCommentsOnPerson(c *gin.Context, id int, params GetCommentsOnPersonParams)
|
||||
// Edit comment on person's profile by ID
|
||||
// (PATCH /comment/{id})
|
||||
EditComment(c *gin.Context, id int, params EditCommentParams)
|
||||
// Comment on person's profile by ID
|
||||
// (POST /comment/{id})
|
||||
CommentOnPerson(c *gin.Context, id int, params CommentOnPersonParams)
|
||||
// Get family tree by person ID
|
||||
// (GET /family-tree)
|
||||
GetFamilyTreeById(c *gin.Context, params GetFamilyTreeByIdParams)
|
||||
@@ -760,6 +818,210 @@ func (siw *ServerInterfaceWrapper) CreateAdminRelationship(c *gin.Context) {
|
||||
siw.Handler.CreateAdminRelationship(c, id1, id2, params)
|
||||
}
|
||||
|
||||
// DeleteCommentOnPerson operation middleware
|
||||
func (siw *ServerInterfaceWrapper) DeleteCommentOnPerson(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params DeleteCommentOnPersonParams
|
||||
|
||||
headers := c.Request.Header
|
||||
|
||||
// ------------- Required header parameter "X-User-ID" -------------
|
||||
if valueList, found := headers[http.CanonicalHeaderKey("X-User-ID")]; found {
|
||||
var XUserID int
|
||||
n := len(valueList)
|
||||
if n != 1 {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-User-ID, got %d", n), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "X-User-ID", valueList[0], &XUserID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-User-ID: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params.XUserID = XUserID
|
||||
|
||||
} else {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Header parameter X-User-ID is required, but not found"), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
middleware(c)
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
siw.Handler.DeleteCommentOnPerson(c, id, params)
|
||||
}
|
||||
|
||||
// GetCommentsOnPerson operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetCommentsOnPerson(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params GetCommentsOnPersonParams
|
||||
|
||||
headers := c.Request.Header
|
||||
|
||||
// ------------- Required header parameter "X-User-ID" -------------
|
||||
if valueList, found := headers[http.CanonicalHeaderKey("X-User-ID")]; found {
|
||||
var XUserID int
|
||||
n := len(valueList)
|
||||
if n != 1 {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-User-ID, got %d", n), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "X-User-ID", valueList[0], &XUserID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-User-ID: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params.XUserID = XUserID
|
||||
|
||||
} else {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Header parameter X-User-ID is required, but not found"), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
middleware(c)
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
siw.Handler.GetCommentsOnPerson(c, id, params)
|
||||
}
|
||||
|
||||
// EditComment operation middleware
|
||||
func (siw *ServerInterfaceWrapper) EditComment(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params EditCommentParams
|
||||
|
||||
headers := c.Request.Header
|
||||
|
||||
// ------------- Required header parameter "X-User-ID" -------------
|
||||
if valueList, found := headers[http.CanonicalHeaderKey("X-User-ID")]; found {
|
||||
var XUserID int
|
||||
n := len(valueList)
|
||||
if n != 1 {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-User-ID, got %d", n), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "X-User-ID", valueList[0], &XUserID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-User-ID: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params.XUserID = XUserID
|
||||
|
||||
} else {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Header parameter X-User-ID is required, but not found"), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
middleware(c)
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
siw.Handler.EditComment(c, id, params)
|
||||
}
|
||||
|
||||
// CommentOnPerson operation middleware
|
||||
func (siw *ServerInterfaceWrapper) CommentOnPerson(c *gin.Context) {
|
||||
|
||||
var err error
|
||||
|
||||
// ------------- Path parameter "id" -------------
|
||||
var id int
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "id", c.Param("id"), &id, runtime.BindStyledParameterOptions{Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter id: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Parameter object where we will unmarshal all parameters from the context
|
||||
var params CommentOnPersonParams
|
||||
|
||||
headers := c.Request.Header
|
||||
|
||||
// ------------- Required header parameter "X-User-ID" -------------
|
||||
if valueList, found := headers[http.CanonicalHeaderKey("X-User-ID")]; found {
|
||||
var XUserID int
|
||||
n := len(valueList)
|
||||
if n != 1 {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Expected one value for X-User-ID, got %d", n), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = runtime.BindStyledParameterWithOptions("simple", "X-User-ID", valueList[0], &XUserID, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationHeader, Explode: false, Required: true})
|
||||
if err != nil {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Invalid format for parameter X-User-ID: %w", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
params.XUserID = XUserID
|
||||
|
||||
} else {
|
||||
siw.ErrorHandler(c, fmt.Errorf("Header parameter X-User-ID is required, but not found"), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
for _, middleware := range siw.HandlerMiddlewares {
|
||||
middleware(c)
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
siw.Handler.CommentOnPerson(c, id, params)
|
||||
}
|
||||
|
||||
// GetFamilyTreeById operation middleware
|
||||
func (siw *ServerInterfaceWrapper) GetFamilyTreeById(c *gin.Context) {
|
||||
|
||||
@@ -1842,6 +2104,10 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options
|
||||
router.DELETE(options.BaseURL+"/admin/:id1/:id2", wrapper.DeleteAdminRelationship)
|
||||
router.GET(options.BaseURL+"/admin/:id1/:id2", wrapper.GetAdminRelationship)
|
||||
router.POST(options.BaseURL+"/admin/:id1/:id2", wrapper.CreateAdminRelationship)
|
||||
router.DELETE(options.BaseURL+"/comment/:id", wrapper.DeleteCommentOnPerson)
|
||||
router.GET(options.BaseURL+"/comment/:id", wrapper.GetCommentsOnPerson)
|
||||
router.PATCH(options.BaseURL+"/comment/:id", wrapper.EditComment)
|
||||
router.POST(options.BaseURL+"/comment/:id", wrapper.CommentOnPerson)
|
||||
router.GET(options.BaseURL+"/family-tree", wrapper.GetFamilyTreeById)
|
||||
router.GET(options.BaseURL+"/family-tree-with-spouses", wrapper.GetFamilyTreeWithSpousesById)
|
||||
router.GET(options.BaseURL+"/health", wrapper.HealthCheck)
|
||||
|
Reference in New Issue
Block a user