Skip to content
This repository was archived by the owner on May 6, 2025. It is now read-only.

Commit 0f04a75

Browse files
committed
Add client unit tests
This commit adds the unit tests for the REST client library Signed-off-by: Adolfo García Veytia (Puerco) <[email protected]>
1 parent 981404f commit 0f04a75

1 file changed

Lines changed: 192 additions & 0 deletions

File tree

pkg/client/client_test.go

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// Copyright 2024 Stacklok, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package client provides a rest client to talk to the Trusty API.
16+
package client
17+
18+
import (
19+
"context"
20+
"fmt"
21+
"io"
22+
"net/http"
23+
"strings"
24+
"testing"
25+
26+
"github.com/stacklok/trusty-sdk-go/pkg/types"
27+
"github.com/stretchr/testify/require"
28+
)
29+
30+
// fakeClient mocks the http client used by the trusty client
31+
type fakeClient struct {
32+
resp *http.Response
33+
err error
34+
}
35+
36+
func (fc *fakeClient) Do(_ *http.Request) (*http.Response, error) {
37+
return fc.resp, fc.err
38+
}
39+
40+
func buildReader(s string) io.ReadCloser {
41+
stringReader := strings.NewReader(s)
42+
return io.NopCloser(stringReader)
43+
}
44+
45+
func TestReport(t *testing.T) {
46+
t.Parallel()
47+
respBody := `{"package_name":"requestts","package_type":"pypi"}`
48+
49+
testdep := &types.Dependency{
50+
Name: "requestts",
51+
Ecosystem: 1,
52+
}
53+
54+
for _, tc := range []struct {
55+
name string
56+
dep *types.Dependency
57+
prepare func(*fakeClient)
58+
expected *types.Reply
59+
mustErr bool
60+
}{
61+
{
62+
name: "normal",
63+
dep: testdep,
64+
prepare: func(fc *fakeClient) {
65+
fc.resp = &http.Response{
66+
StatusCode: http.StatusOK,
67+
Body: buildReader(respBody),
68+
}
69+
},
70+
expected: &types.Reply{
71+
PackageName: "requestts",
72+
PackageType: "pypi",
73+
},
74+
},
75+
{
76+
name: "no-dep-name",
77+
dep: &types.Dependency{
78+
Ecosystem: 1,
79+
},
80+
prepare: func(_ *fakeClient) {},
81+
mustErr: true,
82+
},
83+
{
84+
name: "no-dep-ecosystem",
85+
dep: &types.Dependency{
86+
Name: "test",
87+
},
88+
prepare: func(_ *fakeClient) {},
89+
mustErr: true,
90+
},
91+
{
92+
name: "http-fails",
93+
dep: testdep,
94+
prepare: func(fc *fakeClient) {
95+
fc.err = fmt.Errorf("fake error")
96+
},
97+
mustErr: true,
98+
},
99+
{
100+
name: "http-non-200",
101+
dep: testdep,
102+
prepare: func(fc *fakeClient) {
103+
fc.resp = &http.Response{
104+
Body: buildReader(respBody),
105+
Status: "Not found",
106+
StatusCode: 404,
107+
}
108+
},
109+
mustErr: true,
110+
},
111+
{
112+
name: "bad-response-json",
113+
dep: testdep,
114+
prepare: func(fc *fakeClient) {
115+
fc.resp = &http.Response{
116+
Body: buildReader("HEy Fr1end!"),
117+
Status: "OK",
118+
StatusCode: 200,
119+
}
120+
},
121+
mustErr: true,
122+
},
123+
} {
124+
tc := tc
125+
t.Run(tc.name, func(t *testing.T) {
126+
t.Parallel()
127+
fake := &fakeClient{}
128+
tc.prepare(fake)
129+
client := &Trusty{
130+
Options: Options{
131+
HttpClient: fake,
132+
BaseURL: defaultEndpoint,
133+
},
134+
}
135+
136+
res, err := client.Report(context.Background(), tc.dep)
137+
if tc.mustErr {
138+
require.Error(t, err)
139+
return
140+
}
141+
142+
require.NoError(t, err)
143+
require.NotNil(t, res)
144+
require.Equal(t, tc.expected.PackageName, res.PackageName)
145+
})
146+
}
147+
}
148+
149+
func TestUrlFromEndpointAndPaths(t *testing.T) {
150+
t.Parallel()
151+
for _, tc := range []struct {
152+
name string
153+
baseUrl string
154+
endpoint string
155+
params map[string]string
156+
expected string
157+
mustErr bool
158+
}{
159+
{
160+
name: "no-query",
161+
endpoint: "/test/",
162+
baseUrl: defaultEndpoint,
163+
expected: "https://api.trustypkg.dev/test/",
164+
},
165+
{
166+
name: "query-string",
167+
endpoint: "/test/",
168+
baseUrl: defaultEndpoint,
169+
params: map[string]string{"key": "value"},
170+
expected: "https://api.trustypkg.dev/test/?key=value",
171+
},
172+
{
173+
name: "invalid-base",
174+
endpoint: "/test/",
175+
baseUrl: "Even!\nFlow!",
176+
mustErr: true,
177+
},
178+
} {
179+
t.Run(tc.name, func(t *testing.T) {
180+
tc := tc
181+
t.Parallel()
182+
res, err := urlFromEndpointAndPaths(tc.baseUrl, tc.endpoint, tc.params)
183+
if tc.mustErr {
184+
require.Error(t, err)
185+
return
186+
}
187+
require.NoError(t, err)
188+
require.Equal(t, tc.expected, res.String())
189+
190+
})
191+
}
192+
}

0 commit comments

Comments
 (0)