diff --git a/internal/pkg/note/repo/postgres_test.go b/internal/pkg/note/repo/postgres_test.go index 84e03e3..cf2bfa0 100644 --- a/internal/pkg/note/repo/postgres_test.go +++ b/internal/pkg/note/repo/postgres_test.go @@ -1308,3 +1308,53 @@ func TestNotePostgres_UpdateTagOnAllNotes(t *testing.T) { }) } } + +func TestNoteRepo_GetOwnerInfo(t *testing.T) { + tests := []struct { + name string + mockRepoAction func(*pgxpoolmock.MockPgxPool, *mock_metrics.MockDBMetrics, pgx.Rows, uuid.UUID) + Id uuid.UUID + columns []string + expectedErr error + }{ + { + name: "GetOwnerInfo_Success", + mockRepoAction: func(mockPool *pgxpoolmock.MockPgxPool, metr *mock_metrics.MockDBMetrics, pgxRows pgx.Rows, id uuid.UUID) { + mockPool.EXPECT().QueryRow(gomock.Any(), getOwnerInfo, id).Return(pgxRows) + pgxRows.Next() + metr.EXPECT().ObserveResponseTime(gomock.Any(), gomock.Any()).Return() + }, + Id: uuid.NewV4(), + columns: []string{"username", "image_path"}, + expectedErr: nil, + }, + { + name: "GetOwnerInfo_Fail", + mockRepoAction: func(mockPool *pgxpoolmock.MockPgxPool, metr *mock_metrics.MockDBMetrics, pgxRows pgx.Rows, id uuid.UUID) { + mockPool.EXPECT().QueryRow(gomock.Any(), getOwnerInfo, id).Return(pgxRows) + pgxRows.Next() + metr.EXPECT().ObserveResponseTime(gomock.Any(), gomock.Any()).Return() + }, + Id: uuid.NewV4(), + columns: []string{"username", "image_path"}, + expectedErr: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + mockPool := pgxpoolmock.NewMockPgxPool(ctrl) + mockMetrics := mock_metrics.NewMockDBMetrics(ctrl) + defer ctrl.Finish() + + pgxRows := pgxpoolmock.NewRows(tt.columns).AddRow("", "").ToPgxRows() + + tt.mockRepoAction(mockPool, mockMetrics, pgxRows, tt.Id) + + repo := CreateNotePostgres(mockPool, mockMetrics) + _, err := repo.GetOwnerInfo(context.Background(), tt.Id) + + assert.Equal(t, tt.expectedErr, err) + }) + } +} diff --git a/internal/pkg/note/usecase/usecase.go b/internal/pkg/note/usecase/usecase.go index 7e8ace5..041434e 100644 --- a/internal/pkg/note/usecase/usecase.go +++ b/internal/pkg/note/usecase/usecase.go @@ -52,13 +52,13 @@ func (uc *NoteUsecase) GetAllNotes(ctx context.Context, userId uuid.UUID, count return res, err } - for _, response := range res { + for i, response := range res { info, err := uc.baseRepo.GetOwnerInfo(ctx, response.OwnerId) if err != nil { logger.Error(err.Error()) } - response.OwnerInfo = info + res[i].OwnerInfo = info } logger.Info("success") diff --git a/internal/pkg/note/usecase/usecase_test.go b/internal/pkg/note/usecase/usecase_test.go index 1e67df7..4d1adfe 100644 --- a/internal/pkg/note/usecase/usecase_test.go +++ b/internal/pkg/note/usecase/usecase_test.go @@ -250,6 +250,108 @@ func TestNoteUsecase_GetNote(t *testing.T) { } } +func TestNoteUsecase_GetPublicNote(t *testing.T) { + elasticConfig := config.ElasticConfig{ + ElasticIndexName: "notes", + ElasticSearchValueMinLength: 2, + } + + constraintsConfig := config.ConstraintsConfig{ + MaxDepth: 3, + MaxCollaborators: 10, + MaxTags: 10, + MaxSubnotes: 10, + } + + type args struct { + ctx context.Context + noteId uuid.UUID + } + tests := []struct { + name string + repoMocker func(context context.Context, repo *mock_note.MockNoteBaseRepo, args args) + args args + want models.NoteResponse + wantErr bool + }{ + { + name: "TestSuccess", + repoMocker: func(ctx context.Context, repo *mock_note.MockNoteBaseRepo, args args) { + mockResp := models.NoteResponse{ + Note: models.Note{ //мок ответа от уровня репозитория + Id: uuid.FromStringOrNil("c80e3ea8-0813-4731-b6ee-b41604c56f95"), + OwnerId: uuid.FromStringOrNil("a233ea8-0813-4731-b12e-b41604c56f95"), + UpdateTime: time.Time{}, + CreateTime: time.Time{}, + Data: "", + Parent: uuid.UUID{}, + Children: []uuid.UUID{}, + Public: true, + }, + } + + repo.EXPECT().ReadPublicNote(ctx, args.noteId).Return(mockResp, nil).Times(1) + repo.EXPECT().GetOwnerInfo(gomock.Any(), gomock.Any()).Return(models.OwnerInfo{}, nil).Times(1) + }, + args: args{ + context.Background(), + uuid.FromStringOrNil("c80e3ea8-0813-4731-b6ee-b41604c56f95"), + }, + want: models.NoteResponse{ + Note: models.Note{ + Id: uuid.FromStringOrNil("c80e3ea8-0813-4731-b6ee-b41604c56f95"), + OwnerId: uuid.FromStringOrNil("a233ea8-0813-4731-b12e-b41604c56f95"), + UpdateTime: time.Time{}, + CreateTime: time.Time{}, + Data: "", + Parent: uuid.UUID{}, + Children: []uuid.UUID{}, + Public: true, + }, + }, + + wantErr: false, + }, + { + name: "TestFail", + repoMocker: func(ctx context.Context, repo *mock_note.MockNoteBaseRepo, args args) { + mockResp := models.NoteResponse{ //мок ответа от уровня репозитория + + } + + repo.EXPECT().ReadPublicNote(ctx, args.noteId).Return(mockResp, errors.New("error")).Times(1) + }, + args: args{ + context.Background(), + uuid.FromStringOrNil("c80e3ea8-0813-4731-b6ee-b41604c56f95"), + }, + want: models.NoteResponse{}, + + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + repo := mock_note.NewMockNoteBaseRepo(ctl) + searchRepo := mock_note.NewMockNoteSearchRepo(ctl) + uc := CreateNoteUsecase(repo, searchRepo, elasticConfig, constraintsConfig, &sync.WaitGroup{}) + + tt.repoMocker(context.Background(), repo, tt.args) + + got, err := uc.GetPublicNote(tt.args.ctx, tt.args.noteId) + if (err != nil) != tt.wantErr { + t.Errorf("NoteUsecase.GetPublicNote() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NoteUsecase.GetPublicNote() = %v, want %v", got, tt.want) + } + }) + } +} + func TestNoteUsecase_CreateNote(t *testing.T) { elasticConfig := config.ElasticConfig{ ElasticIndexName: "notes", @@ -849,6 +951,25 @@ func TestNoteUsecase_addCollaboratorRecursive(t *testing.T) { }, }, + { + name: "Test_addCollaboratorReqursive_Success", + wantErr: false, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + Children: []uuid.UUID{noteId}, + }, + }, nil) + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().AddCollaborator(gomock.Any(), noteId, guestId).Return("", nil).Times(2) + + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -2486,3 +2607,131 @@ func TestNoteUsecase_GetSharedAttachList(t *testing.T) { }) } } + +func TestNoteUsecase_changeModeRecursive(t *testing.T) { + elasticConfig := config.ElasticConfig{ + ElasticIndexName: "notes", + ElasticSearchValueMinLength: 2, + } + + constraintsConfig := config.ConstraintsConfig{ + MaxDepth: 3, + MaxCollaborators: 10, + MaxTags: 4, + MaxSubnotes: 10, + } + + noteId := uuid.NewV4() + guestId := uuid.NewV4() + + tests := []struct { + name string + repoMocker func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) + isPublic bool + wantErr bool + }{ + { + name: "Test_changeModeRecursive_ReadError", + wantErr: true, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{}, errors.New("error")) + }, + isPublic: true, + }, + { + name: "Test_changeModeRecursive_Public_Error", + wantErr: true, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().SetPublic(gomock.Any(), noteId).Return(errors.New("error")) + }, + isPublic: true, + }, + { + name: "Test_changeModeRecursive_Private_Error", + wantErr: true, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().SetPrivate(gomock.Any(), noteId).Return(errors.New("error")) + }, + isPublic: false, + }, + { + name: "Test_changeModeRecursive_NoChildren", + wantErr: false, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().SetPublic(gomock.Any(), noteId).Return(nil) + }, + isPublic: true, + }, + { + name: "Test_changeModeRecursive_Public_Success", + wantErr: false, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + Children: []uuid.UUID{noteId}, + }, + }, nil) + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().SetPublic(gomock.Any(), noteId).Return(nil).Times(2) + }, + isPublic: true, + }, + { + name: "Test_changeModeRecursive_Private_Success", + wantErr: false, + repoMocker: func(context context.Context, baseRepo *mock_note.MockNoteBaseRepo, searchRepo *mock_note.MockNoteSearchRepo) { + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + Children: []uuid.UUID{noteId}, + }, + }, nil) + baseRepo.EXPECT().ReadNote(gomock.Any(), noteId, gomock.Any()).Return(models.NoteResponse{ + Note: models.Note{ + Id: noteId, + }, + }, nil) + baseRepo.EXPECT().SetPrivate(gomock.Any(), noteId).Return(nil).Times(2) + }, + isPublic: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctl := gomock.NewController(t) + defer ctl.Finish() + repo := mock_note.NewMockNoteBaseRepo(ctl) + searchRepo := mock_note.NewMockNoteSearchRepo(ctl) + uc := CreateNoteUsecase(repo, searchRepo, elasticConfig, constraintsConfig, &sync.WaitGroup{}) + + tt.repoMocker(context.Background(), repo, searchRepo) + + err := uc.changeModeRecursive(context.Background(), noteId, guestId, tt.isPublic) + if (err != nil) != tt.wantErr { + t.Errorf("NoteUsecase.changeModeRecursive error = %v, wantErr %v", err, tt.wantErr) + return + } + + }) + } +} diff --git a/nginx.conf b/nginx.conf index 057f666..0aff959 100644 --- a/nginx.conf +++ b/nginx.conf @@ -3,8 +3,8 @@ events {} http { include mime.types; - limit_req_zone $binary_remote_addr zone=ip:5m rate=200r/s; - limit_conn_zone $binary_remote_addr zone=addr:5m; + limit_req_zone $binary_remote_addr zone=ip:1m rate=1000r/s; + limit_conn_zone $binary_remote_addr zone=addr:1m; server { listen 443 ssl;