github.com/gudimz/urlShortener@v0.0.0-20230129195305-c8ee33059a67/internal/server/handler_test.go (about)

     1  package server
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"github.com/gudimz/urlShortener/internal/config"
     7  	"github.com/gudimz/urlShortener/internal/db/postgres"
     8  	"github.com/gudimz/urlShortener/internal/shorten"
     9  	shorten2 "github.com/gudimz/urlShortener/internal/storage/shorten"
    10  	"github.com/gudimz/urlShortener/pkg/logging"
    11  	"github.com/labstack/echo/v4"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  	"net/http"
    15  	"net/http/httptest"
    16  	"os"
    17  	"path/filepath"
    18  	"strings"
    19  	"testing"
    20  )
    21  
    22  var resp struct {
    23  	Message string `json:"message"`
    24  }
    25  
    26  func TestHandler(t *testing.T) {
    27  	// save current path
    28  	testDir, err := os.Getwd()
    29  	if err != nil {
    30  		panic(err)
    31  	}
    32  	//change directory for read config
    33  	if err := os.Chdir("../../"); err != nil {
    34  		panic(err)
    35  	}
    36  
    37  	var (
    38  		cfg    = config.GetConfig()
    39  		logger = logging.GetLogger()
    40  	)
    41  
    42  	dbPool, err := postgres.NewClient(context.Background(), cfg.Postgres)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	defer dbPool.Close()
    47  
    48  	var (
    49  		storage   = shorten2.NewStorage(dbPool, logger)
    50  		shortener = shorten.NewService(storage)
    51  	)
    52  
    53  	t.Run("Create new short url for a given URL", func(t *testing.T) {
    54  		const body = `{"short_url": "youtube","url": "https://www.youtube.com"}`
    55  		var (
    56  			recorder = httptest.NewRecorder()
    57  			request  = httptest.NewRequest(http.MethodPost, "/create", strings.NewReader(body))
    58  			e        = echo.New()
    59  			ctx      = e.NewContext(request, recorder)
    60  			handler  = NewHandler(shortener, logger)
    61  		)
    62  		e.Validator = NewValidator()
    63  		request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
    64  
    65  		require.NoError(t, handler.CreateShorten(ctx))
    66  		assert.Equal(t, http.StatusOK, recorder.Code)
    67  
    68  		require.NoError(t, json.NewDecoder(recorder.Body).Decode(&resp), &resp)
    69  		assert.NotEmpty(t, resp.Message)
    70  	})
    71  
    72  	t.Run("Check two identical short_url", func(t *testing.T) {
    73  		const body = `{"short_url": "google","url": "https://www.google.com"}`
    74  		var (
    75  			recorder = httptest.NewRecorder()
    76  			request  = httptest.NewRequest(http.MethodPost, "/create", strings.NewReader(body))
    77  			e        = echo.New()
    78  			ctx      = e.NewContext(request, recorder)
    79  			handler  = NewHandler(shortener, logger)
    80  		)
    81  		e.Validator = NewValidator()
    82  		request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
    83  
    84  		require.NoError(t, handler.CreateShorten(ctx))
    85  		assert.Equal(t, http.StatusOK, recorder.Code)
    86  
    87  		require.NoError(t, json.NewDecoder(recorder.Body).Decode(&resp), &resp)
    88  		assert.NotEmpty(t, resp.Message)
    89  
    90  		recorder = httptest.NewRecorder()
    91  		request = httptest.NewRequest(http.MethodPost, "/create", strings.NewReader(body))
    92  		request.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
    93  		ctx = e.NewContext(request, recorder)
    94  
    95  		var httpErr *echo.HTTPError
    96  		require.ErrorAs(t, handler.CreateShorten(ctx), &httpErr)
    97  		assert.Equal(t, http.StatusConflict, httpErr.Code)
    98  		assert.Contains(t, httpErr.Message, "short url already exist")
    99  	})
   100  
   101  	t.Run("Check redirect success", func(t *testing.T) {
   102  		const (
   103  			shortUrl  = "google"
   104  			originUrl = "https://www.google.com"
   105  		)
   106  		var (
   107  			recorder = httptest.NewRecorder()
   108  			request  = httptest.NewRequest(http.MethodGet, "/"+shortUrl, nil)
   109  			e        = echo.New()
   110  			ctx      = e.NewContext(request, recorder)
   111  			handler  = NewHandler(shortener, logger)
   112  		)
   113  
   114  		ctx.SetPath("/:short_url")
   115  		ctx.SetParamNames("short_url")
   116  		ctx.SetParamValues(shortUrl)
   117  
   118  		require.NoError(t, handler.Redirect(ctx))
   119  		assert.Equal(t, http.StatusMovedPermanently, recorder.Code)
   120  		assert.Equal(t, originUrl, recorder.Header().Get("Location"))
   121  	})
   122  
   123  	t.Run("Check redirect not found", func(t *testing.T) {
   124  		const (
   125  			shortUrl = "not_google"
   126  		)
   127  		var (
   128  			recorder = httptest.NewRecorder()
   129  			request  = httptest.NewRequest(http.MethodGet, "/"+shortUrl, nil)
   130  			e        = echo.New()
   131  			ctx      = e.NewContext(request, recorder)
   132  			handler  = NewHandler(shortener, logger)
   133  		)
   134  
   135  		ctx.SetPath("/:short_url")
   136  		ctx.SetParamNames("short_url")
   137  		ctx.SetParamValues(shortUrl)
   138  
   139  		var httpErr *echo.HTTPError
   140  		require.ErrorAs(t, handler.Redirect(ctx), &httpErr)
   141  		assert.Equal(t, http.StatusNotFound, httpErr.Code)
   142  	})
   143  
   144  	t.Run("Delete all short url", func(t *testing.T) {
   145  		const (
   146  			shortUrlFirst  = "google"
   147  			shortUrlSecond = "youtube"
   148  		)
   149  		var (
   150  			recorder = httptest.NewRecorder()
   151  			request  = httptest.NewRequest(http.MethodDelete, "/delete/", nil)
   152  			e        = echo.New()
   153  			ctx      = e.NewContext(request, recorder)
   154  			handler  = NewHandler(shortener, logger)
   155  		)
   156  		e.Validator = NewValidator()
   157  		ctx.SetPath("/delete/:short_url")
   158  		ctx.SetParamNames("short_url")
   159  		ctx.SetParamValues(shortUrlFirst)
   160  
   161  		require.NoError(t, handler.DeleteShorten(ctx))
   162  		assert.Equal(t, http.StatusNoContent, recorder.Code)
   163  
   164  		recorder = httptest.NewRecorder()
   165  		request = httptest.NewRequest(http.MethodDelete, "/delete/", nil)
   166  		ctx = e.NewContext(request, recorder)
   167  
   168  		ctx.SetPath("/delete/:short_url")
   169  		ctx.SetParamNames("short_url")
   170  		ctx.SetParamValues(shortUrlSecond)
   171  
   172  		require.NoError(t, handler.DeleteShorten(ctx))
   173  		assert.Equal(t, http.StatusNoContent, recorder.Code)
   174  	})
   175  
   176  	// delete dir with logs
   177  	err = os.RemoveAll(filepath.Join(testDir, "logs"))
   178  	if err != nil && !os.IsExist(err) {
   179  		panic(err)
   180  	}
   181  }