From 560fc3fbcc9cc0e8f3ef25d3701bcbec12499612 Mon Sep 17 00:00:00 2001 From: itsscb Date: Sat, 23 Sep 2023 22:00:09 +0200 Subject: [PATCH] ft/adds more tests for api.account --- api/account_test.go | 311 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 282 insertions(+), 29 deletions(-) diff --git a/api/account_test.go b/api/account_test.go index 719ee38..a6fe385 100644 --- a/api/account_test.go +++ b/api/account_test.go @@ -82,21 +82,21 @@ func TestCreateAccountAPI(t *testing.T) { // require.Equal(t, http.StatusUnauthorized, recorder.Code) // }, // }, - // { - // name: "BadRequest", - // body: gin.H{ - // "email": account.Email, - // }, - // buildStubs: func(store *mockdb.MockStore) { - // store.EXPECT(). - // CreateAccount(gomock.Any(), gomock.Any()). - // Times(1). - // Return(db.Account{}, sql.ErrConnDone) - // }, - // checkResponse: func(recorder *httptest.ResponseRecorder) { - // require.Equal(t, http.StatusBadRequest, recorder.Code) - // }, - // }, + { + name: "BadRequest", + body: gin.H{ + "email": account.Email, + }, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + CreateAccount(gomock.Any(), gomock.Any()). + Times(0). + Return(db.Account{}, sql.ErrConnDone) + }, + checkResponse: func(recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recorder.Code) + }, + }, /* { name: "InvalidCurrency", body: gin.H{ @@ -140,29 +140,272 @@ func TestCreateAccountAPI(t *testing.T) { } } +// func TestGetAccountAPI(t *testing.T) { +// account := randomAccount() + +// ctrl := gomock.NewController(t) +// defer ctrl.Finish() + +// store := mockdb.NewMockStore(ctrl) + +// store.EXPECT().GetAccount(gomock.Any(), gomock.Eq(account.ID)). +// Times(1). +// Return(account, nil) + +// server := NewServer(config, store) +// recorder := httptest.NewRecorder() + +// uri := fmt.Sprintf("/accounts/%d", account.ID) +// req, err := http.NewRequest(http.MethodGet, uri, nil) +// require.NoError(t, err) + +// server.router.ServeHTTP(recorder, req) + +// require.Equal(t, http.StatusOK, recorder.Code) +// requireBodyMatchAccount(t, recorder.Body, account) +// } + func TestGetAccountAPI(t *testing.T) { account := randomAccount() - ctrl := gomock.NewController(t) - defer ctrl.Finish() + testCases := []struct { + name string + accountID int64 + buildStubs func(store *mockdb.MockStore) + checkResponse func(t *testing.T, recoder *httptest.ResponseRecorder) + }{ + { + name: "OK", + accountID: account.ID, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + GetAccount(gomock.Any(), gomock.Eq(account.ID)). + Times(1). + Return(account, nil) + }, + checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusOK, recorder.Code) + requireBodyMatchAccount(t, recorder.Body, account) + }, + }, + // { + // name: "UnauthorizedUser", + // accountID: account.ID, + // setupAuth: func(t *testing.T, request *http.Request, tokenMaker token.Maker) { + // addAuthorization(t, request, tokenMaker, authorizationTypeBearer, "unauthorized_user", time.Minute) + // }, + // buildStubs: func(store *mockdb.MockStore) { + // store.EXPECT(). + // GetAccount(gomock.Any(), gomock.Eq(account.ID)). + // Times(1). + // Return(account, nil) + // }, + // checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + // require.Equal(t, http.StatusUnauthorized, recorder.Code) + // }, + // }, + // { + // name: "NoAuthorization", + // accountID: account.ID, + // buildStubs: func(store *mockdb.MockStore) { + // store.EXPECT(). + // GetAccount(gomock.Any(), gomock.Any()). + // Times(0) + // }, + // checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + // require.Equal(t, http.StatusUnauthorized, recorder.Code) + // }, + // }, + { + name: "NotFound", + accountID: account.ID, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + GetAccount(gomock.Any(), gomock.Eq(account.ID)). + Times(1). + Return(db.Account{}, sql.ErrNoRows) + }, + checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusNotFound, recorder.Code) + }, + }, + // { + // name: "InternalError", + // accountID: account.ID, + // buildStubs: func(store *mockdb.MockStore) { + // store.EXPECT(). + // GetAccount(gomock.Any(), gomock.Eq(account.ID)). + // Times(1). + // Return(db.Account{}, sql.ErrConnDone) + // }, + // checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + // require.Equal(t, http.StatusInternalServerError, recorder.Code) + // }, + // }, + { + name: "InvalidID", + accountID: 0, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + GetAccount(gomock.Any(), gomock.Any()). + Times(0) + }, + checkResponse: func(t *testing.T, recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recorder.Code) + }, + }, + } - store := mockdb.NewMockStore(ctrl) + for i := range testCases { + tc := testCases[i] - store.EXPECT().GetAccount(gomock.Any(), gomock.Eq(account.ID)). - Times(1). - Return(account, nil) + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() - server := NewServer(config, store) - recorder := httptest.NewRecorder() + store := mockdb.NewMockStore(ctrl) + tc.buildStubs(store) - uri := fmt.Sprintf("/accounts/%d", account.ID) - req, err := http.NewRequest(http.MethodGet, uri, nil) - require.NoError(t, err) + server := NewServer(config, store) + recorder := httptest.NewRecorder() - server.router.ServeHTTP(recorder, req) + url := fmt.Sprintf("/accounts/%d", tc.accountID) + request, err := http.NewRequest(http.MethodGet, url, nil) + require.NoError(t, err) - require.Equal(t, http.StatusOK, recorder.Code) - requireBodyMatchAccount(t, recorder.Body, account) + server.router.ServeHTTP(recorder, request) + tc.checkResponse(t, recorder) + }) + } +} + +func TestListAccountsAPI(t *testing.T) { + + n := 5 + accounts := make([]db.Account, n) + for i := 0; i < n; i++ { + accounts[i] = randomAccount() + } + + type Query struct { + pageID int + pageSize int + } + + testCases := []struct { + name string + query Query + buildStubs func(store *mockdb.MockStore) + checkResponse func(recoder *httptest.ResponseRecorder) + }{ + { + name: "OK", + query: Query{ + pageID: 1, + pageSize: n, + }, + buildStubs: func(store *mockdb.MockStore) { + arg := db.ListAccountsParams{ + Limit: int32(n), + Offset: 0, + } + + store.EXPECT(). + ListAccounts(gomock.Any(), gomock.Eq(arg)). + Times(1). + Return(accounts, nil) + }, + checkResponse: func(recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusOK, recorder.Code) + requireBodyMatchAccounts(t, recorder.Body, accounts) + }, + }, + // { + // name: "NoAuthorization", + // query: Query{ + // pageID: 1, + // pageSize: n, + // }, + // buildStubs: func(store *mockdb.MockStore) { + // store.EXPECT(). + // ListAccounts(gomock.Any(), gomock.Any()). + // Times(0) + // }, + // checkResponse: func(recorder *httptest.ResponseRecorder) { + // require.Equal(t, http.StatusUnauthorized, recorder.Code) + // }, + // }, + { + name: "EmptyQuery", + query: Query{}, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + ListAccounts(gomock.Any(), gomock.Any()). + Times(0) + }, + checkResponse: func(recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recorder.Code) + }, + }, + { + name: "InvalidPageID", + query: Query{ + pageID: -1, + pageSize: n, + }, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + ListAccounts(gomock.Any(), gomock.Any()). + Times(0) + }, + checkResponse: func(recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recorder.Code) + }, + }, + { + name: "InvalidPageSize", + query: Query{ + pageID: 1, + pageSize: 100000, + }, + buildStubs: func(store *mockdb.MockStore) { + store.EXPECT(). + ListAccounts(gomock.Any(), gomock.Any()). + Times(0) + }, + checkResponse: func(recorder *httptest.ResponseRecorder) { + require.Equal(t, http.StatusBadRequest, recorder.Code) + }, + }, + } + + for i := range testCases { + tc := testCases[i] + + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + store := mockdb.NewMockStore(ctrl) + tc.buildStubs(store) + + server := NewServer(config, store) + recorder := httptest.NewRecorder() + + url := "/accounts" + request, err := http.NewRequest(http.MethodGet, url, nil) + require.NoError(t, err) + + // Add query parameters to request URL + q := request.URL.Query() + q.Add("pageid", fmt.Sprintf("%d", tc.query.pageID)) + q.Add("pagesize", fmt.Sprintf("%d", tc.query.pageSize)) + request.URL.RawQuery = q.Encode() + + server.router.ServeHTTP(recorder, request) + tc.checkResponse(recorder) + }) + } } func randomAccount() db.Account { @@ -197,3 +440,13 @@ func requireBodyMatchAccount(t *testing.T, body *bytes.Buffer, account db.Accoun require.NoError(t, err) require.Equal(t, account, getAccount) } + +func requireBodyMatchAccounts(t *testing.T, body *bytes.Buffer, accounts []db.Account) { + data, err := io.ReadAll(body) + require.NoError(t, err) + + var gotAccounts []db.Account + err = json.Unmarshal(data, &gotAccounts) + require.NoError(t, err) + require.Equal(t, accounts, gotAccounts) +}