move lastfm mock client stuff to a new package so we can reuse it

for the artistcache test
This commit is contained in:
sentriz
2023-09-14 00:00:47 +01:00
parent c374577328
commit a15b584fda
9 changed files with 82 additions and 104 deletions

View File

@@ -29,10 +29,12 @@ type Client struct {
httpClient *http.Client
}
func NewClientCustom(httpClient *http.Client) *Client {
return &Client{httpClient: httpClient}
}
func NewClient() *Client {
return &Client{
httpClient: http.DefaultClient,
}
return NewClientCustom(http.DefaultClient)
}
func getParamSignature(params url.Values, secret string) string {

View File

@@ -1,44 +1,21 @@
package lastfm
import (
"context"
"crypto/md5"
"crypto/tls"
_ "embed"
"encoding/xml"
"fmt"
"net"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/stretchr/testify/require"
"go.senan.xyz/gonic/scrobble/lastfm/mockclient"
)
func httpClientMock(handler http.Handler) (http.Client, func()) {
server := httptest.NewTLSServer(handler)
client := http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return net.Dial(network, server.Listener.Addr().String())
},
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, //nolint:gosec
},
},
}
return client, server.Close
}
//go:embed testdata/artist_get_info_response.xml
var artistGetInfoResponse string
func TestArtistGetInfo(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getInfo"},
@@ -49,11 +26,8 @@ func TestArtistGetInfo(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(artistGetInfoResponse))
}))
defer shutdown()
client := Client{&httpClient}
w.Write(mockclient.ArtistGetInfoResponse)
})}
// act
actual, err := client.ArtistGetInfo("apiKey1", "Artist 1")
@@ -118,10 +92,10 @@ func TestArtistGetInfo(t *testing.T) {
}, actual)
}
func TestArtistGetInfo_clientRequestFails(t *testing.T) {
func TestArtistGetInfoClientRequestFails(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getInfo"},
@@ -132,10 +106,7 @@ func TestArtistGetInfo_clientRequestFails(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusInternalServerError)
}))
defer shutdown()
client := Client{&httpClient}
})}
// act
actual, err := client.ArtistGetInfo("apiKey1", "Artist 1")
@@ -145,13 +116,10 @@ func TestArtistGetInfo_clientRequestFails(t *testing.T) {
require.Zero(actual)
}
//go:embed testdata/artist_get_top_tracks_response.xml
var artistGetTopTracksResponse string
func TestArtistGetTopTracks(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getTopTracks"},
@@ -162,11 +130,8 @@ func TestArtistGetTopTracks(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(artistGetTopTracksResponse))
}))
defer shutdown()
client := Client{&httpClient}
w.Write(mockclient.ArtistGetTopTracksResponse)
})}
// act
actual, err := client.ArtistGetTopTracks("apiKey1", "artist1")
@@ -222,7 +187,7 @@ func TestArtistGetTopTracks(t *testing.T) {
func TestArtistGetTopTracks_clientRequestFails(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getTopTracks"},
@@ -233,10 +198,7 @@ func TestArtistGetTopTracks_clientRequestFails(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusInternalServerError)
}))
defer shutdown()
client := Client{&httpClient}
})}
// act
actual, err := client.ArtistGetTopTracks("apiKey1", "artist1")
@@ -246,13 +208,10 @@ func TestArtistGetTopTracks_clientRequestFails(t *testing.T) {
require.Zero(actual)
}
//go:embed testdata/artist_get_similar_response.xml
var artistGetSimilarResponse string
func TestArtistGetSimilar(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getSimilar"},
@@ -263,11 +222,8 @@ func TestArtistGetSimilar(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(artistGetSimilarResponse))
}))
defer shutdown()
client := Client{&httpClient}
w.Write(mockclient.ArtistGetSimilarResponse)
})}
// act
actual, err := client.ArtistGetSimilar("apiKey1", "artist1")
@@ -331,7 +287,7 @@ func TestArtistGetSimilar(t *testing.T) {
func TestArtistGetSimilar_clientRequestFails(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"artist.getSimilar"},
@@ -342,10 +298,7 @@ func TestArtistGetSimilar_clientRequestFails(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusInternalServerError)
}))
defer shutdown()
client := Client{&httpClient}
})}
// act
actual, err := client.ArtistGetSimilar("apiKey1", "artist1")
@@ -355,13 +308,10 @@ func TestArtistGetSimilar_clientRequestFails(t *testing.T) {
require.Zero(actual)
}
//go:embed testdata/track_get_similar_response.xml
var trackGetSimilarResponse string
func TestTrackGetSimilarTracks(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"track.getSimilar"},
@@ -373,11 +323,8 @@ func TestTrackGetSimilarTracks(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(trackGetSimilarResponse))
}))
defer shutdown()
client := Client{&httpClient}
w.Write(mockclient.TrackGetSimilarResponse)
})}
// act
actual, err := client.TrackGetSimilarTracks("apiKey1", "artist1", "track1")
@@ -430,7 +377,7 @@ func TestTrackGetSimilarTracks(t *testing.T) {
func TestTrackGetSimilarTracks_clientRequestFails(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"track.getSimilar"},
@@ -442,10 +389,7 @@ func TestTrackGetSimilarTracks_clientRequestFails(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusInternalServerError)
}))
defer shutdown()
client := Client{&httpClient}
})}
// act
actual, err := client.TrackGetSimilarTracks("apiKey1", "artist1", "track1")
@@ -455,13 +399,10 @@ func TestTrackGetSimilarTracks_clientRequestFails(t *testing.T) {
require.Zero(actual)
}
//go:embed testdata/get_session_response.xml
var getSessionResponse string
func TestGetSession(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"auth.getSession"},
@@ -473,11 +414,8 @@ func TestGetSession(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(getSessionResponse))
}))
defer shutdown()
client := Client{&httpClient}
w.Write(mockclient.GetSessionResponse)
})}
// act
actual, err := client.GetSession("apiKey1", "secret1", "token1")
@@ -487,10 +425,10 @@ func TestGetSession(t *testing.T) {
require.Equal("sessionKey1", actual)
}
func TestGetSession_clientRequestFails(t *testing.T) {
func TestGetSessioeClientRequestFails(t *testing.T) {
// arrange
require := require.New(t)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodGet, r.Method)
require.Equal(url.Values{
"method": []string{"auth.getSession"},
@@ -502,10 +440,7 @@ func TestGetSession_clientRequestFails(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusInternalServerError)
}))
defer shutdown()
client := Client{&httpClient}
})}
// act
actual, err := client.GetSession("apiKey1", "secret1", "token1")

View File

@@ -0,0 +1,42 @@
package mockclient
import (
"context"
"crypto/tls"
_ "embed"
"net"
"net/http"
"net/http/httptest"
"testing"
)
func New(t testing.TB, handler http.HandlerFunc) *http.Client {
server := httptest.NewTLSServer(handler)
t.Cleanup(server.Close)
return &http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return net.Dial(network, server.Listener.Addr().String())
},
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, //nolint:gosec
},
},
}
}
//go:embed artist_get_info_response.xml
var ArtistGetInfoResponse []byte
//go:embed artist_get_top_tracks_response.xml
var ArtistGetTopTracksResponse []byte
//go:embed artist_get_similar_response.xml
var ArtistGetSimilarResponse []byte
//go:embed track_get_similar_response.xml
var TrackGetSimilarResponse []byte
//go:embed get_session_response.xml
var GetSessionResponse []byte

View File

@@ -9,6 +9,7 @@ import (
_ "github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/require"
"go.senan.xyz/gonic/db"
"go.senan.xyz/gonic/scrobble/lastfm/mockclient"
)
func TestScrobble(t *testing.T) {
@@ -44,7 +45,7 @@ func TestScrobble(t *testing.T) {
stamp := time.Date(2023, 8, 12, 12, 34, 1, 200, time.UTC)
httpClient, shutdown := httpClientMock(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := Client{mockclient.New(t, func(w http.ResponseWriter, r *http.Request) {
require.Equal(http.MethodPost, r.Method)
require.Equal(url.Values{
"album": []string{"album1"},
@@ -64,12 +65,10 @@ func TestScrobble(t *testing.T) {
require.Equal(baseURL, "https://"+r.Host+r.URL.Path)
w.WriteHeader(http.StatusOK)
w.Write([]byte(artistGetTopTracksResponse))
}))
defer shutdown()
w.Write(mockclient.ArtistGetTopTracksResponse)
})}
client := &Client{&httpClient}
scrobbler := NewScrobbler(testDB, client)
scrobbler := NewScrobbler(testDB, &client)
// act
err = scrobbler.Scrobble(user, track, stamp, true)
@@ -78,7 +77,7 @@ func TestScrobble(t *testing.T) {
require.NoError(err)
}
func TestScrobble_returnsWithoutLastFMSession(t *testing.T) {
func TestScrobbleReturnsWithoutLastFMSession(t *testing.T) {
// arrange
t.Parallel()
require := require.New(t)
@@ -92,7 +91,7 @@ func TestScrobble_returnsWithoutLastFMSession(t *testing.T) {
require.NoError(err)
}
func TestScrobble_failsWithoutLastFMAPIKey(t *testing.T) {
func TestScrobbleFailsWithoutLastFMAPIKey(t *testing.T) {
// arrange
t.Parallel()
require := require.New(t)