From 6d122a5c7127f6d5c32a0f8a60d19be3ac6d248b Mon Sep 17 00:00:00 2001 From: shredd0r Date: Fri, 8 Aug 2025 15:00:28 +0300 Subject: [PATCH] Add new method in MediaManager --- media.go | 70 +++++++++++++++++++++++++++++-- media_test.go | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 4 deletions(-) diff --git a/media.go b/media.go index f3d7451..eecd38f 100644 --- a/media.go +++ b/media.go @@ -6,10 +6,9 @@ import ( const ( ActionRetrieveMedia = "retrieveMediaFile" - // TODO - // storeMediaFile - // getMediaFileNames - // deleteMediaFile + ActionStoreMedia = "storeMediaFile" + ActionGetMediaNames = "getMediaFileNames" + ActionDeleteMedia = "deleteMediaFile" ) type ( @@ -17,12 +16,28 @@ type ( MediaManager interface { // Returns the contents of the file encoded in base64 RetrieveMediaFile(filename string) (*string, *errors.RestErr) + StoreMediaFile(filename string, encodedMediaContent string) (*string, *errors.RestErr) + GetMediaFileNames(pattern string) (*[]string, *errors.RestErr) + DeleteMediaFile(filename string) (*string, *errors.RestErr) } ParamsRetrieveMediaFile struct { Filename string `json:"filename,omitempty"` } + ParamsStoreMediaFile struct { + Filename string `json:"filename,omitempty"` + Data string `json:"data,omitempty"` + } + + ParamsGetMediaFileNames struct { + Pattern string `json:"pattern,omitempty"` + } + + ParamsDeleteMediaFile struct { + Filename string `json:"filename,omitempty"` + } + // mediaManager implements MediaManager. mediaManager struct { Client *Client @@ -44,3 +59,50 @@ func (mm *mediaManager) RetrieveMediaFile(filename string) (*string, *errors.Res } return result, nil } + +// StoreMediaFile store media file to Anki storage. +// Method is expecting content of media file encoded in base64. +// The result is a name already stored media file. +// The method returns an error if: +// - the api request to ankiconnect fails. +// - the api returns a http error. +func (mm *mediaManager) StoreMediaFile(filename string, encodedMediaContent string) (*string, *errors.RestErr) { + params := ParamsStoreMediaFile{ + Filename: filename, + Data: encodedMediaContent, + } + + savedFileName, restErr := post[string](mm.Client, ActionStoreMedia, ¶ms) + return savedFileName, restErr +} + +// GetMediaFileNames get array of media file names which match by pattern from Anki storage +// The result is array of media file names +// The method returns an error if: +// - the api request to ankiconnect fails. +// - the api returns a http error. +func (mm *mediaManager) GetMediaFileNames(pattern string) (*[]string, *errors.RestErr) { + params := ParamsGetMediaFileNames{ + Pattern: pattern, + } + foundFileNames, restErr := post[[]string](mm.Client, ActionGetMediaNames, ¶ms) + if restErr != nil { + return nil, restErr + } + return foundFileNames, nil +} + +// DeleteMediaFile delete media file from Anki storage +// The result is deleted media file name +// The method returns an error if: +// - the api request to ankiconnect fails. +func (mm *mediaManager) DeleteMediaFile(filename string) (*string, *errors.RestErr) { + params := ParamsDeleteMediaFile{ + Filename: filename, + } + deletedFilename, restErr := post[string](mm.Client, ActionDeleteMedia, ¶ms) + if restErr != nil { + return nil, restErr + } + return deletedFilename, nil +} diff --git a/media_test.go b/media_test.go index b46e526..c156c1b 100644 --- a/media_test.go +++ b/media_test.go @@ -1,6 +1,7 @@ package ankiconnect import ( + "encoding/base64" "net/http" "testing" @@ -45,3 +46,116 @@ func TestMediaManager_Retrieve(t *testing.T) { assert.Equal(t, "some error message", restErr.Message) }) } + +func TestMediaManager_Store(t *testing.T) { + request := []byte(`{ + "action": "storeMediaFile", + "version": 6, + "params": { + "filename": "_test_store.txt", + "data": "c3RvcmUgbWVkaWEgZmlsZSB0ZXN0" + } + }`) + + response := []byte(`{ + "result": "_test_store.txt", + "error": null + }`) + + t.Run("success", func(t *testing.T) { + defer httpmock.Reset() + + registerVerifiedPayload(t, request, response) + + filename := "_test_store.txt" + encodedMediaContent := base64.StdEncoding.EncodeToString([]byte("store media file test")) + savedFileName, restRrr := client.Media.StoreMediaFile(filename, encodedMediaContent) + assert.Nil(t, restRrr) + assert.Equal(t, filename, *savedFileName) + }) + + t.Run("error", func(t *testing.T) { + defer httpmock.Reset() + + registerErrorResponse(t) + + savedFileName, restErr := client.Media.StoreMediaFile("_test_store.txt", "some media content") + assert.NotNil(t, restErr) + assert.Nil(t, savedFileName) + assert.Equal(t, http.StatusBadRequest, restErr.StatusCode) + assert.Equal(t, "some error message", restErr.Message) + }) +} + +func TestManager_Get(t *testing.T) { + request := []byte(`{ + "action": "getMediaFileNames", + "version": 6, + "params": { + "pattern": "*" + } + }`) + + response := []byte(`{ + "result": ["_test_file_1.txt", "_test_file_2.txt"], + "error": null + }`) + + t.Run("success", func(t *testing.T) { + defer httpmock.Reset() + + registerVerifiedPayload(t, request, response) + + filenames, restErr := client.Media.GetMediaFileNames("*") + assert.Nil(t, restErr) + assert.Equal(t, []string{"_test_file_1.txt", "_test_file_2.txt"}, *filenames) + }) + + t.Run("error", func(t *testing.T) { + defer httpmock.Reset() + + registerErrorResponse(t) + + filenames, restErr := client.Media.GetMediaFileNames("*") + assert.NotNil(t, restErr) + assert.Nil(t, filenames) + assert.Equal(t, http.StatusBadRequest, restErr.StatusCode) + assert.Equal(t, "some error message", restErr.Message) + }) +} + +func TestManager_Delete(t *testing.T) { + request := []byte(`{ + "action": "deleteMediaFile", + "version": 6, + "params": { + "filename": "_delete_file_name.txt" + } + }`) + response := []byte(`{ + "result": "_delete_file_name.txt", + "error": null + }`) + + t.Run("success", func(t *testing.T) { + defer httpmock.Reset() + + registerVerifiedPayload(t, request, response) + + deletedFileName, restErr := client.Media.DeleteMediaFile("_delete_file_name.txt") + assert.Nil(t, restErr) + assert.Equal(t, "_delete_file_name.txt", *deletedFileName) + }) + + t.Run("error", func(t *testing.T) { + defer httpmock.Reset() + + registerErrorResponse(t) + + deletedFileName, restErr := client.Media.DeleteMediaFile("_delete_file_name.txt") + assert.NotNil(t, restErr) + assert.Nil(t, deletedFileName) + assert.Equal(t, http.StatusBadRequest, restErr.StatusCode) + assert.Equal(t, "some error message", restErr.Message) + }) +}