github.com/joao-fontenele/go-url-shortener@v1.3.4/pkg/postgres/linkdao_test.go (about)

     1  package postgres
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	"github.com/jackc/pgx/v4/pgxpool"
    13  	"github.com/joao-fontenele/go-url-shortener/pkg/configger"
    14  	"github.com/joao-fontenele/go-url-shortener/pkg/shortener"
    15  )
    16  
    17  func testMain(m *testing.M) int {
    18  	var err error
    19  
    20  	// change dir because default pwd for tests are it's parent dir
    21  	os.Chdir("../../")
    22  
    23  	err = configger.Load()
    24  	if err != nil {
    25  		fmt.Printf("failed to load configs: %v", err)
    26  		return 1
    27  	}
    28  
    29  	env := configger.Get().Env
    30  	if env != "test" {
    31  		fmt.Println("don't run these tests on non dev environment")
    32  		return 1
    33  	}
    34  
    35  	closeDB, err := Connect()
    36  	if err != nil {
    37  		return 1
    38  	}
    39  	defer closeDB()
    40  	return m.Run()
    41  }
    42  
    43  func seedDB(conn *pgxpool.Pool) error {
    44  	_, err := conn.Exec(
    45  		context.Background(),
    46  		"INSERT INTO links (slug, url, createdAt) VALUES ('a1CDz', 'https://www.google.com', '2020-05-01T00:00:00.000Z')",
    47  	)
    48  
    49  	return err
    50  }
    51  
    52  func truncateDB(conn *pgxpool.Pool) error {
    53  	_, err := conn.Exec(context.Background(), "TRUNCATE TABLE links")
    54  
    55  	return err
    56  }
    57  
    58  func TestMain(m *testing.M) {
    59  	os.Exit(testMain(m))
    60  }
    61  
    62  func TestFind(t *testing.T) {
    63  	conn := GetConnection()
    64  	if err := truncateDB(conn); err != nil {
    65  		t.Fatalf("error truncating test database tables: %v", err)
    66  	}
    67  
    68  	err := seedDB(conn)
    69  	if err != nil {
    70  		t.Fatalf("failed to seed db: %v", err)
    71  	}
    72  
    73  	dao := NewLinkDao(conn)
    74  
    75  	tt := []struct {
    76  		Name string
    77  		Slug string
    78  		Want *shortener.Link
    79  		Err  error
    80  	}{
    81  		{
    82  			Name: "FoundSlug",
    83  			Slug: "a1CDz",
    84  			Want: &shortener.Link{
    85  				URL:       "https://www.google.com",
    86  				Slug:      "a1CDz",
    87  				CreatedAt: time.Date(2020, 5, 1, 0, 0, 0, 0, time.UTC),
    88  			},
    89  			Err: nil,
    90  		},
    91  		{
    92  			Name: "NotFoundSlug",
    93  			Slug: "niull",
    94  			Want: nil,
    95  			Err:  shortener.ErrLinkNotFound,
    96  		},
    97  	}
    98  
    99  	for _, test := range tt {
   100  		t.Run(test.Name, func(t *testing.T) {
   101  			var got *shortener.Link
   102  			got, err = dao.Find(context.Background(), test.Slug)
   103  
   104  			if !errors.Is(err, test.Err) {
   105  				t.Fatalf("failed to find the requested link: %v", err)
   106  			}
   107  
   108  			if diff := cmp.Diff(test.Want, got); diff != "" {
   109  				t.Errorf("failed to fetch expected link (-want +got):\n%s", diff)
   110  			}
   111  		})
   112  	}
   113  }
   114  
   115  func TestInsert(t *testing.T) {
   116  	conn := GetConnection()
   117  	if err := truncateDB(conn); err != nil {
   118  		t.Fatalf("error truncating test database tables: %v", err)
   119  	}
   120  
   121  	err := seedDB(conn)
   122  	if err != nil {
   123  		t.Fatalf("failed to seed db: %v", err)
   124  	}
   125  
   126  	dao := NewLinkDao(conn)
   127  
   128  	tt := []struct {
   129  		Name  string
   130  		Link  *shortener.Link
   131  		Error error
   132  	}{
   133  		{
   134  			Name: "Success",
   135  			Link: &shortener.Link{
   136  				URL:  "https://www.google.com?s=golang",
   137  				Slug: "spd91",
   138  			},
   139  			Error: nil,
   140  		},
   141  		{
   142  			Name: "ConflictSlug",
   143  			Link: &shortener.Link{
   144  				URL:  "https://www.google.com?s=golang",
   145  				Slug: "a1CDz",
   146  			},
   147  			Error: shortener.ErrLinkExists,
   148  		},
   149  	}
   150  
   151  	for _, test := range tt {
   152  		t.Run(test.Name, func(t *testing.T) {
   153  			_, err := dao.Insert(context.Background(), test.Link)
   154  
   155  			if !errors.Is(err, test.Error) {
   156  				t.Fatalf("failed to query new inserted link %v", err)
   157  			}
   158  
   159  			if err != nil {
   160  				return
   161  			}
   162  
   163  			inserted := shortener.Link{}
   164  			err = conn.QueryRow(
   165  				context.Background(),
   166  				"SELECT slug, url, createdAt FROM links WHERE slug=$1",
   167  				test.Link.Slug,
   168  			).Scan(&inserted.Slug, &inserted.URL, &inserted.CreatedAt)
   169  
   170  			if err != nil {
   171  				t.Fatalf("Unexpected error querying inserted link: %v", err)
   172  			}
   173  
   174  			if diff := cmp.Diff(test.Link, &inserted); diff != "" {
   175  				t.Errorf("failed to fetch expected link (-want +got):\n%s", diff)
   176  			}
   177  		})
   178  	}
   179  }
   180  
   181  func TestList(t *testing.T) {
   182  	conn := GetConnection()
   183  	if err := truncateDB(conn); err != nil {
   184  		t.Fatalf("error truncating test database tables: %v", err)
   185  	}
   186  
   187  	err := seedDB(conn)
   188  	if err != nil {
   189  		t.Fatalf("failed to seed db: %v", err)
   190  	}
   191  
   192  	dao := NewLinkDao(conn)
   193  
   194  	expectedLinks := []shortener.Link{
   195  		{
   196  			URL:       "https://www.google.com",
   197  			Slug:      "a1CDz",
   198  			CreatedAt: time.Date(2020, 5, 1, 0, 0, 0, 0, time.UTC),
   199  		},
   200  	}
   201  
   202  	tests := []struct {
   203  		Name           string
   204  		ExpectedErr    error
   205  		ExpectedResult []shortener.Link
   206  		Skip           int
   207  		Limit          int
   208  	}{
   209  		{
   210  			Name:           "FirstPageSuccess",
   211  			ExpectedErr:    nil,
   212  			ExpectedResult: expectedLinks,
   213  			Skip:           0,
   214  			Limit:          1,
   215  		},
   216  		{
   217  			Name:           "SecondPageEmpty",
   218  			ExpectedErr:    nil,
   219  			ExpectedResult: []shortener.Link{},
   220  			Skip:           1,
   221  			Limit:          1,
   222  		},
   223  	}
   224  
   225  	for _, tc := range tests {
   226  		t.Run(tc.Name, func(t *testing.T) {
   227  			links, err := dao.List(context.Background(), tc.Limit, tc.Skip)
   228  			if err != nil {
   229  				t.Errorf("Failed to List links: %v", err)
   230  			}
   231  
   232  			if diff := cmp.Diff(tc.ExpectedResult, links); diff != "" {
   233  				t.Errorf("Result links list is not equal to expected (-want +got):\n%s", diff)
   234  			}
   235  		})
   236  	}
   237  }