github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/mock/repository/post.go (about)

     1  package mockrepository
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"math"
     7  	"strconv"
     8  	"strings"
     9  
    10  	"github.com/ngocphuongnb/tetua/app/entities"
    11  	"github.com/ngocphuongnb/tetua/app/repositories"
    12  	"github.com/ngocphuongnb/tetua/app/utils"
    13  )
    14  
    15  type PostRepository struct {
    16  	*Repository[entities.Post]
    17  }
    18  
    19  func (m *PostRepository) Find(ctx context.Context, filters ...*entities.PostFilter) ([]*entities.Post, error) {
    20  	if err, ok := FakeRepoErrors[m.Name+"_find"]; ok && err != nil {
    21  		return nil, err
    22  	}
    23  	if len(filters) == 0 {
    24  		return m.entities, nil
    25  	}
    26  	filter := *filters[0]
    27  	result := make([]*entities.Post, 0)
    28  	if filter.Page < 1 {
    29  		filter.Page = 1
    30  	}
    31  	if filter.Limit < 1 {
    32  		filter.Limit = 10
    33  	}
    34  	offset := (filter.Page - 1) * filter.Limit
    35  
    36  	for index, post := range m.entities {
    37  		if index < offset {
    38  			continue
    39  		}
    40  		if index >= offset+filter.Limit {
    41  			break
    42  		}
    43  
    44  		if filter.Search != "" {
    45  			if !strings.Contains(post.Name, filter.Search) && !strings.Contains(post.Content, filter.Search) {
    46  				continue
    47  			}
    48  		}
    49  
    50  		if len(filter.ExcludeIDs) > 0 && utils.SliceContains(filter.ExcludeIDs, post.ID) {
    51  			continue
    52  		}
    53  
    54  		if len(filter.UserIDs) > 0 && !utils.SliceContains(filter.UserIDs, post.UserID) {
    55  			continue
    56  		}
    57  
    58  		if len(filter.TopicIDs) > 0 && len(utils.SliceOverlap(filter.TopicIDs, post.TopicIDs)) == 0 {
    59  			continue
    60  		}
    61  
    62  		if filter.Publish == "published" && post.Draft {
    63  			continue
    64  		}
    65  		if filter.Publish == "draft" && !post.Draft {
    66  			continue
    67  		}
    68  
    69  		user, err := repositories.User.ByID(context.Background(), post.UserID)
    70  
    71  		if err != nil || user == nil {
    72  			user = &entities.User{
    73  				ID:       post.UserID,
    74  				Username: fmt.Sprintf("testuser%d", post.UserID),
    75  				Provider: "local",
    76  			}
    77  		}
    78  		post.User = user
    79  
    80  		result = append(result, post)
    81  
    82  	}
    83  
    84  	return result, nil
    85  }
    86  
    87  func (m *PostRepository) Count(ctx context.Context, filters ...*entities.PostFilter) (int, error) {
    88  	if len(filters) == 0 {
    89  		return len(m.entities), nil
    90  	}
    91  	filter := *filters[0]
    92  	count := 0
    93  	if filter.Page < 1 {
    94  		filter.Page = 1
    95  	}
    96  	if filter.Limit < 1 {
    97  		filter.Limit = 10
    98  	}
    99  	offset := (filter.Page - 1) * filter.Limit
   100  
   101  	for index, post := range m.entities {
   102  		if index < offset {
   103  			continue
   104  		}
   105  		if index >= offset+filter.Limit {
   106  			break
   107  		}
   108  
   109  		if filter.Search != "" {
   110  			if !strings.Contains(post.Name, filter.Search) && !strings.Contains(post.Content, filter.Search) {
   111  				continue
   112  			}
   113  		}
   114  
   115  		if len(filter.ExcludeIDs) > 0 && utils.SliceContains(filter.ExcludeIDs, post.ID) {
   116  			continue
   117  		}
   118  
   119  		if len(filter.UserIDs) > 0 && !utils.SliceContains(filter.UserIDs, post.UserID) {
   120  			continue
   121  		}
   122  
   123  		if len(filter.TopicIDs) > 0 && len(utils.SliceOverlap(filter.TopicIDs, post.TopicIDs)) == 0 {
   124  			continue
   125  		}
   126  
   127  		if filter.Publish == "published" && post.Draft {
   128  			continue
   129  		}
   130  		if filter.Publish == "draft" && !post.Draft {
   131  			continue
   132  		}
   133  
   134  		count++
   135  	}
   136  
   137  	return count, nil
   138  }
   139  
   140  func (m *PostRepository) Paginate(ctx context.Context, filters ...*entities.PostFilter) (*entities.Paginate[entities.Post], error) {
   141  	if err, ok := FakeRepoErrors[m.Name+"_paginate"]; ok && err != nil {
   142  		return nil, err
   143  	}
   144  
   145  	posts, err := m.Find(ctx, filters...)
   146  	if err != nil {
   147  		return nil, err
   148  	}
   149  
   150  	count, err := m.Count(ctx, filters...)
   151  	if err != nil {
   152  		return nil, err
   153  	}
   154  
   155  	filter := filters[0]
   156  	if filter.Page < 1 {
   157  		filter.Page = 1
   158  	}
   159  	if filter.Limit < 1 {
   160  		filter.Limit = 10
   161  	}
   162  	return &entities.Paginate[entities.Post]{
   163  		Data:        posts,
   164  		PageSize:    filter.Limit,
   165  		PageCurrent: filter.Page,
   166  		Total:       int(math.Ceil(float64(count) / float64(filter.Limit))),
   167  	}, nil
   168  }
   169  
   170  func (m *PostRepository) IncreaseViewCount(ctx context.Context, id int, views int64) error {
   171  	foundPost := false
   172  	m.mu.Lock()
   173  	defer m.mu.Unlock()
   174  
   175  	for index, post := range m.entities {
   176  		if post.ID == id {
   177  			foundPost = true
   178  			post.ViewCount += views
   179  			m.entities[index] = post
   180  		}
   181  	}
   182  
   183  	if !foundPost {
   184  		return &entities.NotFoundError{Message: "post not found with id: " + strconv.Itoa(id)}
   185  	}
   186  
   187  	return nil
   188  }
   189  
   190  func (m *PostRepository) PublishedPostByID(ctx context.Context, id int) (post *entities.Post, err error) {
   191  	if post, err = m.ByID(ctx, id); err != nil {
   192  		return nil, err
   193  	}
   194  
   195  	if post.Draft || !post.Approved {
   196  		return nil, &entities.NotFoundError{Message: "post not found with id: " + strconv.Itoa(id)}
   197  	}
   198  
   199  	return post, nil
   200  }
   201  
   202  func (m *PostRepository) Approve(ctx context.Context, id int) error {
   203  	post, err := m.ByID(ctx, id)
   204  	if err != nil {
   205  		return err
   206  	}
   207  
   208  	post.Approved = true
   209  	_, err = m.Update(ctx, post)
   210  
   211  	return err
   212  }