github.com/kastenhq/syft@v0.0.0-20230821225854-0710af25cdbe/internal/version/update_test.go (about)

     1  package version
     2  
     3  import (
     4  	"net/http"
     5  	"net/http/httptest"
     6  	"testing"
     7  
     8  	hashiVersion "github.com/anchore/go-version"
     9  )
    10  
    11  func TestIsUpdateAvailable(t *testing.T) {
    12  	tests := []struct {
    13  		name          string
    14  		buildVersion  string
    15  		latestVersion string
    16  		code          int
    17  		isAvailable   bool
    18  		newVersion    string
    19  		err           bool
    20  	}{
    21  		{
    22  			name:          "equal",
    23  			buildVersion:  "1.0.0",
    24  			latestVersion: "1.0.0",
    25  			code:          200,
    26  			isAvailable:   false,
    27  			newVersion:    "",
    28  			err:           false,
    29  		},
    30  		{
    31  			name:          "hasUpdate",
    32  			buildVersion:  "1.0.0",
    33  			latestVersion: "1.2.0",
    34  			code:          200,
    35  			isAvailable:   true,
    36  			newVersion:    "1.2.0",
    37  			err:           false,
    38  		},
    39  		{
    40  			name:          "aheadOfLatest",
    41  			buildVersion:  "1.2.0",
    42  			latestVersion: "1.0.0",
    43  			code:          200,
    44  			isAvailable:   false,
    45  			newVersion:    "",
    46  			err:           false,
    47  		},
    48  		{
    49  			name:          "EmptyUpdate",
    50  			buildVersion:  "1.0.0",
    51  			latestVersion: "",
    52  			code:          200,
    53  			isAvailable:   false,
    54  			newVersion:    "",
    55  			err:           true,
    56  		},
    57  		{
    58  			name:          "GarbageUpdate",
    59  			buildVersion:  "1.0.0",
    60  			latestVersion: "hdfjksdhfhkj",
    61  			code:          200,
    62  			isAvailable:   false,
    63  			newVersion:    "",
    64  			err:           true,
    65  		},
    66  		{
    67  			name:          "BadUpdate",
    68  			buildVersion:  "1.0.0",
    69  			latestVersion: "1.0.",
    70  			code:          500,
    71  			isAvailable:   false,
    72  			newVersion:    "",
    73  			err:           true,
    74  		},
    75  		{
    76  			name:          "NoBuildVersion",
    77  			buildVersion:  valueNotProvided,
    78  			latestVersion: "1.0.0",
    79  			code:          200,
    80  			isAvailable:   false,
    81  			newVersion:    "",
    82  			err:           false,
    83  		},
    84  		{
    85  			name:          "SnapshotBuildVersion",
    86  			buildVersion:  "2.0.0-SHAPSHOT-a78bf9c",
    87  			latestVersion: "1.0.0",
    88  			code:          200,
    89  			isAvailable:   false,
    90  			newVersion:    "",
    91  			err:           false,
    92  		},
    93  		{
    94  			name:          "BadUpdateValidVersion",
    95  			buildVersion:  "1.0.0",
    96  			latestVersion: "2.0.0",
    97  			code:          404,
    98  			isAvailable:   false,
    99  			newVersion:    "",
   100  			err:           true,
   101  		},
   102  	}
   103  
   104  	for _, test := range tests {
   105  		t.Run(test.name, func(t *testing.T) {
   106  			// setup mocks
   107  			// local...
   108  			version = test.buildVersion
   109  			// remote...
   110  			handler := http.NewServeMux()
   111  			handler.HandleFunc(latestAppVersionURL.path, func(w http.ResponseWriter, r *http.Request) {
   112  				w.WriteHeader(test.code)
   113  				_, _ = w.Write([]byte(test.latestVersion))
   114  			})
   115  			mockSrv := httptest.NewServer(handler)
   116  			latestAppVersionURL.host = mockSrv.URL
   117  			defer mockSrv.Close()
   118  
   119  			isAvailable, newVersion, err := IsUpdateAvailable()
   120  			if err != nil && !test.err {
   121  				t.Fatalf("got error but expected none: %+v", err)
   122  			} else if err == nil && test.err {
   123  				t.Fatalf("expected error but got none")
   124  			}
   125  
   126  			if newVersion != test.newVersion {
   127  				t.Errorf("unexpected NEW version: %+v", newVersion)
   128  			}
   129  
   130  			if isAvailable != test.isAvailable {
   131  				t.Errorf("unexpected result: %+v", isAvailable)
   132  			}
   133  		})
   134  	}
   135  
   136  }
   137  
   138  func TestFetchLatestApplicationVersion(t *testing.T) {
   139  	tests := []struct {
   140  		name     string
   141  		response string
   142  		code     int
   143  		err      bool
   144  		expected *hashiVersion.Version
   145  	}{
   146  		{
   147  			name:     "gocase",
   148  			response: "1.0.0",
   149  			code:     200,
   150  			expected: hashiVersion.Must(hashiVersion.NewVersion("1.0.0")),
   151  		},
   152  		{
   153  			name:     "garbage",
   154  			response: "garbage",
   155  			code:     200,
   156  			expected: nil,
   157  			err:      true,
   158  		},
   159  		{
   160  			name:     "http 500",
   161  			response: "1.0.0",
   162  			code:     500,
   163  			expected: nil,
   164  			err:      true,
   165  		},
   166  		{
   167  			name:     "http 404",
   168  			response: "1.0.0",
   169  			code:     404,
   170  			expected: nil,
   171  			err:      true,
   172  		},
   173  		{
   174  			name:     "empty",
   175  			response: "",
   176  			code:     200,
   177  			expected: nil,
   178  			err:      true,
   179  		},
   180  		{
   181  			name:     "too long",
   182  			response: "this is really long this is really long this is really long this is really long this is really long this is really long this is really long this is really long ",
   183  			code:     200,
   184  			expected: nil,
   185  			err:      true,
   186  		},
   187  	}
   188  
   189  	for _, test := range tests {
   190  		t.Run(test.name, func(t *testing.T) {
   191  			// setup mock
   192  			handler := http.NewServeMux()
   193  			handler.HandleFunc(latestAppVersionURL.path, func(w http.ResponseWriter, r *http.Request) {
   194  				w.WriteHeader(test.code)
   195  				_, _ = w.Write([]byte(test.response))
   196  			})
   197  			mockSrv := httptest.NewServer(handler)
   198  			latestAppVersionURL.host = mockSrv.URL
   199  			defer mockSrv.Close()
   200  
   201  			actual, err := fetchLatestApplicationVersion()
   202  			if err != nil && !test.err {
   203  				t.Fatalf("got error but expected none: %+v", err)
   204  			} else if err == nil && test.err {
   205  				t.Fatalf("expected error but got none")
   206  			}
   207  
   208  			if err != nil {
   209  				return
   210  			}
   211  
   212  			if actual.String() != test.expected.String() {
   213  				t.Errorf("unexpected version: %+v", actual.String())
   214  			}
   215  		})
   216  	}
   217  
   218  }