-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resources #9
base: main
Are you sure you want to change the base?
Resources #9
Changes from all commits
fa0cfe1
d627194
dba24dc
144cb98
275761c
cfa7e79
acf749c
80a26c2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
.envrc | ||
cover.out | ||
ngrok.yml | ||
cover.out | ||
|
||
*.mp3 | ||
*.ogg | ||
*.opus | ||
*.wav |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,204 @@ | ||
package resources | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"io/ioutil" | ||
"mime/multipart" | ||
"net/http" | ||
"net/http/httputil" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
|
||
"github.com/AlekSi/alice" | ||
) | ||
|
||
type Quota struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported type |
||
Total int | ||
Used int | ||
} | ||
|
||
type Sound struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported type |
||
ID string | ||
SkillID string | ||
Size *int | ||
OriginalName string | ||
CreatedAt time.Time | ||
IsProcessed bool | ||
Error *string | ||
} | ||
|
||
type Client struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported type |
||
SkillID string | ||
OAuthToken string | ||
HTTPClient *http.Client | ||
|
||
// debugging options | ||
Debugf alice.Printf // debug logger | ||
Indent bool // indent requests and responses | ||
StrictDecoder bool // disallow unexpected fields in responses | ||
} | ||
|
||
func (c *Client) do(req *http.Request, respBody interface{}) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cognitive complexity 32 of func |
||
httpClient := c.HTTPClient | ||
if httpClient == nil { | ||
httpClient = http.DefaultClient | ||
} | ||
|
||
var jsonRequst bool | ||
if c.OAuthToken != "" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if statements should only be cuddled with assignments used in the if statement itself (from |
||
req.Header.Set("Authorization", "OAuth "+c.OAuthToken) | ||
} | ||
if req.Body != nil && req.Header.Get("Content-Type") == "" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if statements should only be cuddled with assignments (from |
||
jsonRequst = true | ||
req.Header.Set("Content-Type", "application/json; charset=utf-8") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only cuddled expressions if assigning variable or using from line above (from |
||
} | ||
|
||
if c.Debugf != nil { | ||
if c.Indent && jsonRequst { | ||
b, err := ioutil.ReadAll(req.Body) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var body bytes.Buffer | ||
if err = json.Indent(&body, b, "", " "); err != nil { | ||
return err | ||
} | ||
req.Body = ioutil.NopCloser(&body) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assignments should only be cuddled with other assignments (from |
||
req.ContentLength = int64(body.Len()) | ||
req.TransferEncoding = nil | ||
} | ||
|
||
b, err := httputil.DumpRequestOut(req, jsonRequst) | ||
if err != nil { | ||
return err | ||
} | ||
c.debugf("Request:\n%s", b) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expressions should not be cuddled with blocks (from |
||
} | ||
|
||
resp, err := httpClient.Do(req) | ||
if err != nil { | ||
return err | ||
} | ||
defer resp.Body.Close() //nolint:errcheck | ||
|
||
if c.Debugf != nil { | ||
if c.Indent { | ||
b, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var body bytes.Buffer | ||
if err = json.Indent(&body, b, "", " "); err != nil { | ||
return err | ||
} | ||
resp.Body = ioutil.NopCloser(&body) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assignments should only be cuddled with other assignments (from |
||
resp.ContentLength = int64(body.Len()) | ||
resp.TransferEncoding = nil | ||
} | ||
|
||
b, err := httputil.DumpResponse(resp, true) | ||
if err != nil { | ||
return err | ||
} | ||
c.debugf("Response:\n%s", b) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expressions should not be cuddled with blocks (from |
||
} | ||
|
||
if resp.StatusCode/100 != 2 { | ||
return fmt.Errorf("status code %d", resp.StatusCode) | ||
} | ||
|
||
d := json.NewDecoder(resp.Body) | ||
if c.StrictDecoder { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if statements should only be cuddled with assignments used in the if statement itself (from |
||
d.DisallowUnknownFields() | ||
} | ||
return d.Decode(&respBody) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. return statements should not be cuddled if block has more than two lines (from |
||
} | ||
|
||
func (c *Client) debugf(format string, a ...interface{}) { | ||
if c.Debugf != nil { | ||
c.Debugf(format, a...) | ||
} | ||
} | ||
|
||
type StatusResponse struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported type |
||
Images struct { | ||
Quota Quota | ||
} | ||
Sounds struct { | ||
Quota Quota | ||
} | ||
} | ||
|
||
func (c *Client) Status() (*StatusResponse, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported method |
||
req, err := http.NewRequest("GET", "https://dialogs.yandex.net/api/v1/status", nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var res StatusResponse | ||
if err = c.do(req, &res); err != nil { | ||
return nil, err | ||
} | ||
return &res, nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. return statements should not be cuddled if block has more than two lines (from |
||
} | ||
|
||
func (c *Client) UploadSound(name string, r io.Reader) (*Sound, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported method |
||
var buf bytes.Buffer | ||
mw := multipart.NewWriter(&buf) | ||
fw, err := mw.CreateFormFile("file", name) | ||
if err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only one cuddle assignment allowed before if statement (from |
||
return nil, err | ||
} | ||
if _, err = io.Copy(fw, r); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if statements should only be cuddled with assignments (from |
||
return nil, err | ||
} | ||
if err = mw.Close(); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if statements should only be cuddled with assignments (from |
||
return nil, err | ||
} | ||
|
||
req, err := http.NewRequest("POST", "https://dialogs.yandex.net/api/v1/skills/"+c.SkillID+"/sounds", &buf) | ||
if err != nil { | ||
return nil, err | ||
} | ||
req.Header.Add("Content-Type", mw.FormDataContentType()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expressions should not be cuddled with blocks (from |
||
|
||
var res struct { | ||
Sound Sound | ||
} | ||
if err = c.do(req, &res); err != nil { | ||
return nil, err | ||
} | ||
return &res.Sound, nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. return statements should not be cuddled if block has more than two lines (from |
||
} | ||
|
||
func (c *Client) UploadSoundFile(filename string) (*Sound, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported method |
||
f, err := os.Open(filename) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. G304: Potential file inclusion via variable (from |
||
if err != nil { | ||
return nil, err | ||
} | ||
defer f.Close() //nolint:errcheck | ||
|
||
return c.UploadSound(filepath.Base(filename), f) | ||
} | ||
|
||
func (c *Client) ListSounds() ([]Sound, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported method |
||
req, err := http.NewRequest("GET", "https://dialogs.yandex.net/api/v1/skills/"+c.SkillID+"/sounds", nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var res struct { | ||
Sounds []Sound | ||
Total int | ||
} | ||
if err = c.do(req, &res); err != nil { | ||
return nil, err | ||
} | ||
return res.Sounds, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package resources | ||
|
||
import ( | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
"time" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestClient(t *testing.T) { | ||
if testing.Short() { | ||
t.Skip("-short is passed, skipping integration test") | ||
} | ||
|
||
skillID := os.Getenv("ALICE_TEST_SKILL_ID") | ||
oAuthToken := os.Getenv("ALICE_TEST_OAUTH_TOKEN") | ||
if skillID == "" || oAuthToken == "" { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. only one cuddle assignment allowed before if statement (from |
||
t.Skip("`ALICE_TEST_SKILL_ID` or `ALICE_TEST_OAUTH_TOKEN` is not set, skipping integration test") | ||
} | ||
|
||
c := Client{ | ||
SkillID: skillID, | ||
OAuthToken: oAuthToken, | ||
Indent: true, | ||
StrictDecoder: true, | ||
} | ||
|
||
t.Run("Status", func(t *testing.T) { | ||
c.Debugf = t.Logf | ||
|
||
status, err := c.Status() | ||
require.NoError(t, err) | ||
assert.Equal(t, 104857600, status.Images.Quota.Total) | ||
assert.Equal(t, 1073741824, status.Sounds.Quota.Total) | ||
}) | ||
|
||
t.Run("Sound", func(t *testing.T) { | ||
t.Run("UploadSoundFile", func(t *testing.T) { | ||
c.Debugf = t.Logf | ||
|
||
sound, err := c.UploadSoundFile(filepath.Join("..", "testdata", "go.wav")) | ||
require.NoError(t, err) | ||
require.NotEmpty(t, sound) | ||
assert.NotEmpty(t, skillID, sound.ID) | ||
assert.Equal(t, skillID, sound.SkillID) | ||
assert.Empty(t, sound.Size) | ||
assert.Equal(t, "go.wav", sound.OriginalName) | ||
assert.WithinDuration(t, time.Now(), sound.CreatedAt, 5*time.Second) | ||
assert.False(t, sound.IsProcessed) | ||
assert.Nil(t, sound.Error) | ||
|
||
sounds, err := c.ListSounds() | ||
require.NoError(t, err) | ||
assert.Empty(t, sounds) | ||
}) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ST1000: at least one file in a package should have a package comment (from
stylecheck
)