From d15a363b2c01b48d8d1e5b9483b32b02ef38fc35 Mon Sep 17 00:00:00 2001 From: Reaper Date: Sun, 4 Sep 2022 11:22:23 +0500 Subject: [PATCH] Better testing (#56) * added router, and helper test methods to easily to make unit tests * Added testMethod to check request method, comments, removed unneccessary methods * Added guide on how to create and add new unit tests! --- README.md | 5 +- tests/CONTRIBUTING.md | 55 +++++++++++ tests/analysisService_test.go | 74 +++++---------- tests/analyzerService_test.go | 40 +++----- tests/connectorService_test.go | 42 +++----- tests/intelOwl_test.go | 56 ++++++++++- tests/jobService_test.go | 169 ++++++++++++--------------------- tests/tagService_test.go | 105 ++++++++------------ 8 files changed, 267 insertions(+), 279 deletions(-) create mode 100644 tests/CONTRIBUTING.md diff --git a/README.md b/README.md index d9ef361..fb4ae59 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ $ go get github.com/intelowlproject/go-intelowl ## Usage This library was built with ease of use in mind! Here are some quick examples to get you started. If you need more example you can go to the [examples directory](./examples/) -To start using the gointelowl library you first need to import it: +To start using the go-intelowl library you first need to import it: ``` import "github.com/intelowlproject/go-intelowl/gointelowl" ``` @@ -117,8 +117,7 @@ func main(){ } ``` - -For complete usage of go-intelowl, see the full [package docs](). +For complete usage of go-intelowl, see the full [package docs](https://pkg.go.dev/github.com/intelowlproject/go-intelowl). # Contribute See our [contributor page]() for details how to contribute. If you want to follow the updates, discuss, or just chat then please join our [slack](https://honeynetpublic.slack.com/archives/C01KVGMAKL6) channel we'd love to hear your feedback! diff --git a/tests/CONTRIBUTING.md b/tests/CONTRIBUTING.md new file mode 100644 index 0000000..6e5ada5 --- /dev/null +++ b/tests/CONTRIBUTING.md @@ -0,0 +1,55 @@ +## How unit tests were written +The unit tests were written as a combination of [table driven tests](https://dave.cheney.net/2019/05/07/prefer-table-driven-tests) and the approach used by [go-github](https://github.com/google/go-github) + +Firstly we use a `TestData` struct that has the following fields: +1. `Input` - this is an `interface` as it is to be used as the input required for an endpoint +2. `Data` - this is a `string` as it'll be the `JSON` string that the endpoint is expected to return +2. `StatusCode` - this is an `int` as it is meant to be used as the expected response returned by the endpoint +3. `Want` - the expected struct that the method will return + +Now the reason we made this was that these fields were needed for every endpoint hence combining them into a single struct provided us reusability and flexibility. + +Now the testing suite used go's `httptest` library where we use `httptest.Server` as this setups a test server so that we can easily mock it. We also use `http.ServerMux` to mock our endpoints response. + +## How to add a new test for an endpoint +Lets say IntelOwl added a new endpoint called **supercool** in `Tag`. Now you've implemented the endpoint as a method of `TagService` and now you want to add its unit tests. + +First go to `tagService_test.go` in the `tests` directory and add + +```Go +func TestSuperCoolEndPoint(t *testing.T) { + testCases := make(map[string]TestData) + testCases["simple"] = TestData{ + Input: nil, + Data: `{ "supercool": "you're a great developer :)"}`, + StatusCode: http.StatusOK, + Want: "you're a great developer :)", + } + for name, testCase := range testCases { + // subtest + t.Run(name, func(t *testing.T) { + // setup will give you the client, mux/router, closeServer + client, apiHandler, closeServer := setup() + defer closeServer() + ctx := context.Background() + // now you can use apiHandler to mock how the server will handle this endpoints request + // you can use mux/router's Handle method or HandleFunc + apiHandler.Handle("/api/tag/supercool", func(w http.ResponseWriter, r *http.Request) { + // this is a helper test to check if it is the expected request sent by the client + testMethod(t, r, "GET") + w.Write([]byte(testCase.Data)) + }) + expectedRespone, err := client.TagService.SuperCool(ctx) + if err != nil { + testError(t, testCase, err) + } else { + testWantData(t, testCase.Want, expectedRespone) + } + }) + } +} + +``` + +Great! Now you've added your own unit tests. + diff --git a/tests/analysisService_test.go b/tests/analysisService_test.go index d7d3d0f..8919ff2 100644 --- a/tests/analysisService_test.go +++ b/tests/analysisService_test.go @@ -8,8 +8,6 @@ import ( "path" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" ) @@ -40,23 +38,17 @@ func TestCreateObservableAnalysis(t *testing.T) { } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() + apiHandler.Handle("/api/analyze_observable", serverHandler(t, testCase, "POST")) observableParams, ok := testCase.Input.(gointelowl.ObservableAnalysisParams) if ok { gottenAnalysisResponse, err := client.CreateObservableAnalysis(ctx, &observableParams) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenAnalysisResponse) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenAnalysisResponse) } } }) @@ -98,23 +90,17 @@ func TestCreateMultipleObservableAnalysis(t *testing.T) { for name, testCase := range testCases { t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() + apiHandler.Handle("/api/analyze_multiple_observables", serverHandler(t, testCase, "POST")) ctx := context.Background() multipleObservableParams, ok := testCase.Input.(gointelowl.MultipleObservableAnalysisParams) if ok { gottenMultipleAnalysisResponse, err := client.CreateMultipleObservableAnalysis(ctx, &multipleObservableParams) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenMultipleAnalysisResponse) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenMultipleAnalysisResponse) } } }) @@ -154,23 +140,17 @@ func TestCreateFileAnalysis(t *testing.T) { } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() + apiHandler.Handle("/api/analyze_file", serverHandler(t, testCase, "POST")) ctx := context.Background() fileAnalysisParams, ok := testCase.Input.(gointelowl.FileAnalysisParams) if ok { gottenFileAnalysisResponse, err := client.CreateFileAnalysis(ctx, &fileAnalysisParams) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenFileAnalysisResponse) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenFileAnalysisResponse) } } }) @@ -216,23 +196,17 @@ func TestCreateMultipleFilesAnalysis(t *testing.T) { } for name, testCase := range testCases { t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() + apiHandler.Handle("/api/analyze_mutliple_files", serverHandler(t, testCase, "POST")) ctx := context.Background() multipleFilesAnalysisParams, ok := testCase.Input.(gointelowl.MultipleFileAnalysisParams) if ok { gottenMultipleFilesAnalysisResponse, err := client.CreateMultipleFileAnalysis(ctx, &multipleFilesAnalysisParams) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenMultipleFilesAnalysisResponse) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenMultipleFilesAnalysisResponse) } } }) diff --git a/tests/analyzerService_test.go b/tests/analyzerService_test.go index 99ca1ad..1f2bcc8 100644 --- a/tests/analyzerService_test.go +++ b/tests/analyzerService_test.go @@ -3,11 +3,10 @@ package tests import ( "context" "encoding/json" + "fmt" "net/http" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" ) @@ -83,21 +82,15 @@ func TestAnalyzerServiceGetConfigs(t *testing.T) { for name, testCase := range testCases { // *Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() + apiHandler.Handle("/api/get_analyzer_configs", serverHandler(t, testCase, "GET")) gottenAnalyzerConfigList, err := client.AnalyzerService.GetConfigs(ctx) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, (*gottenAnalyzerConfigList)) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, (*gottenAnalyzerConfigList)) } }) } @@ -124,23 +117,18 @@ func TestAnalyzerServiceHealthCheck(t *testing.T) { for name, testCase := range testCases { // *Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() input, ok := testCase.Input.(string) if ok { + testUrl := fmt.Sprintf("/api/analyzer/%s/healthcheck", input) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "GET")) status, err := client.AnalyzerService.HealthCheck(ctx, input) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, status) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, status) } } }) diff --git a/tests/connectorService_test.go b/tests/connectorService_test.go index 89449b1..c3047b2 100644 --- a/tests/connectorService_test.go +++ b/tests/connectorService_test.go @@ -3,12 +3,11 @@ package tests import ( "context" "encoding/json" + "fmt" "net/http" "sort" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" ) @@ -41,21 +40,15 @@ func TestConnectorServiceGetConfigs(t *testing.T) { for name, testCase := range testCases { // *Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() + apiHandler.Handle("/api/get_connector_configs", serverHandler(t, testCase, "GET")) gottenConnectorConfigList, err := client.ConnectorService.GetConfigs(ctx) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, (*gottenConnectorConfigList)) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, *gottenConnectorConfigList) } }) } @@ -82,23 +75,18 @@ func TestConnectorServiceHealthCheck(t *testing.T) { for name, testCase := range testCases { // *Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() input, ok := testCase.Input.(string) if ok { - status, err := client.AnalyzerService.HealthCheck(ctx, input) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + testUrl := fmt.Sprintf("/api/connector/%s/healthcheck", input) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "GET")) + status, err := client.ConnectorService.HealthCheck(ctx, input) + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, status) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, status) } } }) diff --git a/tests/intelOwl_test.go b/tests/intelOwl_test.go index c69175e..c9e0d16 100644 --- a/tests/intelOwl_test.go +++ b/tests/intelOwl_test.go @@ -4,7 +4,10 @@ import ( "fmt" "net/http" "net/http/httptest" + "testing" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" "github.com/sirupsen/logrus" ) @@ -17,8 +20,53 @@ type TestData struct { Want interface{} } -func NewTestServer(testData *TestData) *httptest.Server { - return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// Setting up the router, client, and test server +func setup() (testClient gointelowl.IntelOwlClient, apiHandler *http.ServeMux, closeServer func()) { + + apiHandler = http.NewServeMux() + + testServer := httptest.NewServer(apiHandler) + + testClient = NewTestIntelOwlClient(testServer.URL) + + return testClient, apiHandler, testServer.Close + +} + +// Helper test +// Testing the request method is as expected +func testMethod(t *testing.T, request *http.Request, wantedMethod string) { + t.Helper() + if got := request.Method; got != wantedMethod { + t.Errorf("Request method: %v, want %v", got, wantedMethod) + } +} + +// Helper test +// Testing if it was an Error response +func testError(t *testing.T, testData TestData, err error) { + t.Helper() + if testData.StatusCode < http.StatusOK || testData.StatusCode >= http.StatusBadRequest { + diff := cmp.Diff(testData.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) + if diff != "" { + t.Fatalf(diff) + } + } +} + +// Helper test +// Testing if it was the expected response +func testWantData(t *testing.T, want interface{}, data interface{}) { + t.Helper() + diff := cmp.Diff(want, data) + if diff != "" { + t.Fatalf(diff) + } +} + +func serverHandler(t *testing.T, testData TestData, expectedMethod string) http.Handler { + handler := func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, expectedMethod) if testData.StatusCode > 0 { w.WriteHeader(testData.StatusCode) } @@ -29,7 +77,9 @@ func NewTestServer(testData *TestData) *httptest.Server { fmt.Fprintf(w, "{}") } } - })) + } + + return http.HandlerFunc(handler) } func NewTestIntelOwlClient(url string) gointelowl.IntelOwlClient { diff --git a/tests/jobService_test.go b/tests/jobService_test.go index 4601455..3e1c62c 100644 --- a/tests/jobService_test.go +++ b/tests/jobService_test.go @@ -3,11 +3,10 @@ package tests import ( "context" "encoding/json" + "fmt" "net/http" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" ) @@ -29,17 +28,15 @@ func TestJobServiceList(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() + apiHandler.Handle("/api/jobs", serverHandler(t, testCase, "GET")) gottenJobList, err := client.JobService.List(ctx) if err != nil { - t.Fatalf("Error listing Jobs: %v", err) - } - diff := cmp.Diff(testCase.Want, gottenJobList) - if diff != "" { - t.Fatalf(diff) + testError(t, testCase, err) + } else { + testWantData(t, testCase.Want, gottenJobList) } }) } @@ -74,24 +71,19 @@ func TestJobServiceGet(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { jobId := uint64(id) + testUrl := fmt.Sprintf("/api/jobs/%d", jobId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "GET")) gottenJob, err := client.JobService.Get(ctx, jobId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenJob) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenJob) } } else { t.Fatalf("Casting failed!") @@ -123,24 +115,19 @@ func TestJobServiceDownloadSample(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { jobId := uint64(id) + testUrl := fmt.Sprintf("/api/jobs/%d/download_sample", jobId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "GET")) gottenSample, err := client.JobService.DownloadSample(ctx, jobId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenSample) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenSample) } } else { t.Fatalf("Casting failed!") @@ -171,24 +158,19 @@ func TestJobServiceDelete(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { jobId := uint64(id) + testUrl := fmt.Sprintf("/api/jobs/%d", jobId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "DELETE")) isDeleted, err := client.JobService.Delete(ctx, jobId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, isDeleted) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, isDeleted) } } }) @@ -225,24 +207,19 @@ func TestJobServiceKill(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { jobId := uint64(id) + testUrl := fmt.Sprintf("/api/jobs/%d/kill", jobId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PATCH")) isDeleted, err := client.JobService.Kill(ctx, jobId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, isDeleted) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, isDeleted) } } }) @@ -293,23 +270,18 @@ func TestJobServiceKillAnalyzer(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() inputData, ok := testCase.Input.(input) if ok { + testUrl := fmt.Sprintf("/api/jobs/%d/analyzer/%s/kill", inputData.Id, inputData.Name) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PATCH")) isDeleted, err := client.JobService.KillAnalyzer(ctx, inputData.Id, inputData.Name) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, isDeleted) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, isDeleted) } } }) @@ -331,23 +303,18 @@ func TestJobServiceRetryAnalyzer(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() inputData, ok := testCase.Input.(input) if ok { + testUrl := fmt.Sprintf("/api/jobs/%d/analyzer/%s/retry", inputData.Id, inputData.Name) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PATCH")) retry, err := client.JobService.RetryAnalyzer(ctx, inputData.Id, inputData.Name) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, retry) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, retry) } } }) @@ -369,23 +336,18 @@ func TestJobServiceKillConnector(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() inputData, ok := testCase.Input.(input) if ok { + testUrl := fmt.Sprintf("/api/jobs/%d/connector/%s/kill", inputData.Id, inputData.Name) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PATCH")) isDeleted, err := client.JobService.KillConnector(ctx, inputData.Id, inputData.Name) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, isDeleted) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, isDeleted) } } }) @@ -407,23 +369,18 @@ func TestJobServiceRetryConnector(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() inputData, ok := testCase.Input.(input) if ok { + testUrl := fmt.Sprintf("/api/jobs/%d/connector/%s/retry", inputData.Id, inputData.Name) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PATCH")) retry, err := client.JobService.RetryConnector(ctx, inputData.Id, inputData.Name) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, retry) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, retry) } } }) diff --git a/tests/tagService_test.go b/tests/tagService_test.go index 4edf03a..eb3119d 100644 --- a/tests/tagService_test.go +++ b/tests/tagService_test.go @@ -2,18 +2,18 @@ package tests import ( "context" + "fmt" "net/http" "testing" - "github.com/google/go-cmp/cmp" - "github.com/google/go-cmp/cmp/cmpopts" "github.com/intelowlproject/go-intelowl/gointelowl" ) // * Test for TagService.List method! func TestTagServiceList(t *testing.T) { - // * table test case + testCases := make(map[string]TestData) + testCases["simple"] = TestData{ Input: nil, Data: `[ @@ -41,31 +41,27 @@ func TestTagServiceList(t *testing.T) { }, } for name, testCase := range testCases { - //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() + apiHandler.Handle("/api/tags", serverHandler(t, testCase, "GET")) ctx := context.Background() gottenTagList, err := client.TagService.List(ctx) if err != nil { - t.Fatalf("Error listing tags: %v", err) - } - diff := cmp.Diff(testCase.Want, (*gottenTagList)) - if diff != "" { - t.Fatalf(diff) + testError(t, testCase, err) + } else { + testWantData(t, testCase.Want, (*gottenTagList)) } }) } } func TestTagServiceGet(t *testing.T) { - // *table test case testCases := make(map[string]TestData) testCases["simple"] = TestData{ Input: 1, - Data: `{"id": 1,"label": "TEST","color": "#1c71d8"}`, StatusCode: http.StatusOK, + Data: `{"id": 1,"label": "TEST","color": "#1c71d8"}`, Want: &gointelowl.Tag{ ID: 1, Label: "TEST", @@ -74,37 +70,34 @@ func TestTagServiceGet(t *testing.T) { } testCases["cantFind"] = TestData{ Input: 9000, - Data: `{"detail": "Not found."}`, StatusCode: http.StatusNotFound, + Data: `{"detail": "Not found."}`, Want: &gointelowl.IntelOwlError{ StatusCode: http.StatusNotFound, Message: `{"detail": "Not found."}`, }, } + for name, testCase := range testCases { - //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { tagId := uint64(id) + testUrl := fmt.Sprintf("/api/tags/%d", tagId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "GET")) gottenTag, err := client.TagService.Get(ctx, tagId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + // Helper test to check error + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenTag) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenTag) } } else { t.Fatalf("Casting failed!") + t.Fatalf("You didn't pass the correct Input datatype") } }) } @@ -141,23 +134,17 @@ func TestTagServiceCreate(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() + apiHandler.Handle("/api/tags", serverHandler(t, testCase, "POST")) tagParams, ok := testCase.Input.(gointelowl.TagParams) if ok { gottenTag, err := client.TagService.Create(ctx, &tagParams) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenTag) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenTag) } } else { t.Fatalf("Casting failed!") @@ -186,26 +173,21 @@ func TestTagServiceUpdate(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() tag, ok := testCase.Input.(gointelowl.Tag) if ok { + testUrl := fmt.Sprintf("/api/tags/%d", tag.ID) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "PUT")) gottenTag, err := client.TagService.Update(ctx, tag.ID, &gointelowl.TagParams{ Label: tag.Label, Color: tag.Color, }) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, gottenTag) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, gottenTag) } } }) @@ -224,24 +206,19 @@ func TestTagServiceDelete(t *testing.T) { for name, testCase := range testCases { //* Subtest t.Run(name, func(t *testing.T) { - testServer := NewTestServer(&testCase) - defer testServer.Close() - client := NewTestIntelOwlClient(testServer.URL) + client, apiHandler, closeServer := setup() + defer closeServer() ctx := context.Background() id, ok := testCase.Input.(int) if ok { tagId := uint64(id) + testUrl := fmt.Sprintf("/api/tags/%d", tagId) + apiHandler.Handle(testUrl, serverHandler(t, testCase, "DELETE")) isDeleted, err := client.TagService.Delete(ctx, tagId) - if testCase.StatusCode < http.StatusOK || testCase.StatusCode >= http.StatusBadRequest { - diff := cmp.Diff(testCase.Want, err, cmpopts.IgnoreFields(gointelowl.IntelOwlError{}, "Response")) - if diff != "" { - t.Fatalf(diff) - } + if err != nil { + testError(t, testCase, err) } else { - diff := cmp.Diff(testCase.Want, isDeleted) - if diff != "" { - t.Fatalf(diff) - } + testWantData(t, testCase.Want, isDeleted) } } })