Repository: xanzy/go-gitlab
Pull request #1758 (2023-07-19 15:34:37)

Add snippet repository storage move APIs
Adds api endpoints from https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html


Patch:
diff --git a/gitlab.go b/gitlab.go
index 2f646f5..c199188 100644
--- a/gitlab.go
+++ b/gitlab.go
@@ -206,6 +206,7 @@ type Client struct {
 	Services                     *ServicesService
 	Settings                     *SettingsService
 	Sidekiq                      *SidekiqService
+	SnippetRepositoryStorageMove *SnippetRepositoryStorageMoveService
 	Snippets                     *SnippetsService
 	SystemHooks                  *SystemHooksService
 	Tags                         *TagsService
@@ -425,6 +426,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
 	c.Settings = &SettingsService{client: c}
 	c.Sidekiq = &SidekiqService{client: c}
 	c.Snippets = &SnippetsService{client: c}
+	c.SnippetRepositoryStorageMove = &SnippetRepositoryStorageMoveService{client: c}
 	c.SystemHooks = &SystemHooksService{client: c}
 	c.Tags = &TagsService{client: c}
 	c.Todos = &TodosService{client: c}
diff --git a/pipelines.go b/pipelines.go
index 75a8b6c..df52318 100644
--- a/pipelines.go
+++ b/pipelines.go
@@ -115,7 +115,7 @@ type PipelineTestCases struct {
 	Classname      string          `json:"classname"`
 	File           string          `json:"file"`
 	ExecutionTime  float64         `json:"execution_time"`
-	SystemOutput   interface{}     `json:"system_output"`
+	SystemOutput   string          `json:"system_output"`
 	StackTrace     string          `json:"stack_trace"`
 	AttachmentURL  string          `json:"attachment_url"`
 	RecentFailures *RecentFailures `json:"recent_failures"`
diff --git a/project_repository_storage_move.go b/project_repository_storage_move.go
index 52c136e..4911e61 100644
--- a/project_repository_storage_move.go
+++ b/project_repository_storage_move.go
@@ -36,41 +36,44 @@ type ProjectRepositoryStorageMoveService struct {
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html
 type ProjectRepositoryStorageMove struct {
-	ID                     int        `json:"id"`
-	CreatedAt              *time.Time `json:"created_at"`
-	State                  string     `json:"state"`
-	SourceStorageName      string     `json:"source_storage_name"`
-	DestinationStorageName string     `json:"destination_storage_name"`
-	Project                struct {
-		ID                int        `json:"id"`
-		Description       string     `json:"description"`
-		Name              string     `json:"name"`
-		NameWithNamespace string     `json:"name_with_namespace"`
-		Path              string     `json:"path"`
-		PathWithNamespace string     `json:"path_with_namespace"`
-		CreatedAt         *time.Time `json:"created_at"`
-	} `json:"project"`
+	ID                     int                `json:"id"`
+	CreatedAt              *time.Time         `json:"created_at"`
+	State                  string             `json:"state"`
+	SourceStorageName      string             `json:"source_storage_name"`
+	DestinationStorageName string             `json:"destination_storage_name"`
+	Project                *RepositoryProject `json:"project"`
 }
 
-// RetrieveAllStorageMovesOptions represents the available
+type RepositoryProject struct {
+	ID                int        `json:"id"`
+	Description       string     `json:"description"`
+	Name              string     `json:"name"`
+	NameWithNamespace string     `json:"name_with_namespace"`
+	Path              string     `json:"path"`
+	PathWithNamespace string     `json:"path_with_namespace"`
+	CreatedAt         *time.Time `json:"created_at"`
+}
+
+// RetrieveAllProjectStorageMovesOptions represents the available
 // RetrieveAllStorageMoves() options.
 //
-// GitLab API docs: https://docs.gitlab.com/ee/api/project_repository_storage_moves.html
-type RetrieveAllStorageMovesOptions ListOptions
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/project_repository_storage_moves.html
+type RetrieveAllProjectStorageMovesOptions ListOptions
 
-// RetrieveAllStorageMoves retrieves all repository storage moves accessible by
-// the authenticated user.
+// RetrieveAllStorageMoves retrieves all project repository storage moves
+// accessible by the authenticated user.
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#retrieve-all-project-repository-storage-moves
-func (s ProjectRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) {
-	req, err := s.client.NewRequest(http.MethodGet, "project_repository_storage_moves", opts, options)
+func (p ProjectRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) {
+	req, err := p.client.NewRequest(http.MethodGet, "project_repository_storage_moves", opts, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
 	var psms []*ProjectRepositoryStorageMove
-	resp, err := s.client.Do(req, &psms)
+	resp, err := p.client.Do(req, &psms)
 	if err != nil {
 		return nil, resp, err
 	}
@@ -83,16 +86,16 @@ func (s ProjectRepositoryStorageMoveService) RetrieveAllStorageMoves(opts Retrie
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#retrieve-all-repository-storage-moves-for-a-project
-func (s ProjectRepositoryStorageMoveService) RetrieveAllStorageMovesForProject(project int, opts RetrieveAllStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) {
+func (p ProjectRepositoryStorageMoveService) RetrieveAllStorageMovesForProject(project int, opts RetrieveAllProjectStorageMovesOptions, options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) {
 	u := fmt.Sprintf("projects/%d/repository_storage_moves", project)
 
-	req, err := s.client.NewRequest(http.MethodGet, u, opts, options)
+	req, err := p.client.NewRequest(http.MethodGet, u, opts, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
 	var psms []*ProjectRepositoryStorageMove
-	resp, err := s.client.Do(req, &psms)
+	resp, err := p.client.Do(req, &psms)
 	if err != nil {
 		return nil, resp, err
 	}
@@ -100,20 +103,20 @@ func (s ProjectRepositoryStorageMoveService) RetrieveAllStorageMovesForProject(p
 	return psms, resp, err
 }
 
-// GetStorageMove gets a single repository storage move.
+// GetStorageMove gets a single project repository storage move.
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#get-a-single-project-repository-storage-move
-func (s ProjectRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
+func (p ProjectRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
 	u := fmt.Sprintf("project_repository_storage_moves/%d", repositoryStorage)
 
-	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	req, err := p.client.NewRequest(http.MethodGet, u, nil, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
 	psm := new(ProjectRepositoryStorageMove)
-	resp, err := s.client.Do(req, psm)
+	resp, err := p.client.Do(req, psm)
 	if err != nil {
 		return nil, resp, err
 	}
@@ -125,16 +128,16 @@ func (s ProjectRepositoryStorageMoveService) GetStorageMove(repositoryStorage in
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#get-a-single-repository-storage-move-for-a-project
-func (s ProjectRepositoryStorageMoveService) GetStorageMoveForProject(project int, repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
+func (p ProjectRepositoryStorageMoveService) GetStorageMoveForProject(project int, repositoryStorage int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
 	u := fmt.Sprintf("projects/%d/repository_storage_moves/%d", project, repositoryStorage)
 
-	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	req, err := p.client.NewRequest(http.MethodGet, u, nil, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
 	psm := new(ProjectRepositoryStorageMove)
-	resp, err := s.client.Do(req, psm)
+	resp, err := p.client.Do(req, psm)
 	if err != nil {
 		return nil, resp, err
 	}
@@ -142,42 +145,36 @@ func (s ProjectRepositoryStorageMoveService) GetStorageMoveForProject(project in
 	return psm, resp, err
 }
 
-// ScheduleAllStorageMoves schedules all repositories to be moved.
+// ScheduleStorageMoveForProject schedule a repository to be moved for a project.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#schedule-repository-storage-moves-for-all-projects-on-a-storage-shard
-func (s ProjectRepositoryStorageMoveService) ScheduleAllStorageMoves(options ...RequestOptionFunc) ([]*ProjectRepositoryStorageMove, *Response, error) {
-	req, err := s.client.NewRequest(http.MethodPost, "project_repository_storage_moves", nil, options)
+// https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#schedule-a-repository-storage-move-for-a-project
+func (p ProjectRepositoryStorageMoveService) ScheduleStorageMoveForProject(project int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
+	u := fmt.Sprintf("projects/%d/repository_storage_moves", project)
+
+	req, err := p.client.NewRequest(http.MethodPost, u, nil, options)
 	if err != nil {
 		return nil, nil, err
 	}
 
-	var psms []*ProjectRepositoryStorageMove
-	resp, err := s.client.Do(req, &psms)
+	psm := new(ProjectRepositoryStorageMove)
+	resp, err := p.client.Do(req, psm)
 	if err != nil {
 		return nil, resp, err
 	}
 
-	return psms, resp, err
+	return psm, resp, err
 }
 
-// ScheduleStorageMoveForProject schedule a repository to be moved for a project.
+// ScheduleAllStorageMoves schedules all repositories to be moved.
 //
 // GitLab API docs:
-// https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#schedule-a-repository-storage-move-for-a-project
-func (s ProjectRepositoryStorageMoveService) ScheduleStorageMoveForProject(project int, options ...RequestOptionFunc) (*ProjectRepositoryStorageMove, *Response, error) {
-	u := fmt.Sprintf("projects/%d/repository_storage_moves", project)
-
-	req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	psm := new(ProjectRepositoryStorageMove)
-	resp, err := s.client.Do(req, psm)
+// https://docs.gitlab.com/ee/api/project_repository_storage_moves.html#schedule-repository-storage-moves-for-all-projects-on-a-storage-shard
+func (p ProjectRepositoryStorageMoveService) ScheduleAllStorageMoves(options ...RequestOptionFunc) (*Response, error) {
+	req, err := p.client.NewRequest(http.MethodPost, "project_repository_storage_moves", nil, options)
 	if err != nil {
-		return nil, resp, err
+		return nil, err
 	}
 
-	return psm, resp, err
+	return p.client.Do(req, nil)
 }
diff --git a/settings.go b/settings.go
index 92a1ef6..3ac4ead 100644
--- a/settings.go
+++ b/settings.go
@@ -189,7 +189,6 @@ type Settings struct {
 	HousekeepingFullRepackPeriod                          int               `json:"housekeeping_full_repack_period"`
 	HousekeepingGcPeriod                                  int               `json:"housekeeping_gc_period"`
 	HousekeepingIncrementalRepackPeriod                   int               `json:"housekeeping_incremental_repack_period"`
-	HousekeepingOptimizeRepositoryPeriod                  int               `json:"housekeeping_optimize_repository_period"`
 	ImportSources                                         []string          `json:"import_sources"`
 	InactiveProjectsDeleteAfterMonths                     int               `json:"inactive_projects_delete_after_months"`
 	InactiveProjectsMinSizeMB                             int               `json:"inactive_projects_min_size_mb"`
@@ -568,7 +567,6 @@ type UpdateSettingsOptions struct {
 	HousekeepingFullRepackPeriod                          *int               `url:"housekeeping_full_repack_period,omitempty" json:"housekeeping_full_repack_period,omitempty"`
 	HousekeepingGcPeriod                                  *int               `url:"housekeeping_gc_period,omitempty" json:"housekeeping_gc_period,omitempty"`
 	HousekeepingIncrementalRepackPeriod                   *int               `url:"housekeeping_incremental_repack_period,omitempty" json:"housekeeping_incremental_repack_period,omitempty"`
-	HousekeepingOptimizedepositoryPeriod                  *int               `url:"housekeeping_optimize_repository_period,omitempty" json:"housekeeping_optimize_repository_period,omitempty"`
 	ImportSources                                         *[]string          `url:"import_sources,omitempty" json:"import_sources,omitempty"`
 	InactiveProjectsDeleteAfterMonths                     *int               `url:"inactive_projects_delete_after_months,omitempty" json:"inactive_projects_delete_after_months,omitempty"`
 	InactiveProjectsMinSizeMB                             *int               `url:"inactive_projects_min_size_mb,omitempty" json:"inactive_projects_min_size_mb,omitempty"`
diff --git a/snippet_repository_storage_move.go b/snippet_repository_storage_move.go
new file mode 100644
index 0000000..119051b
--- /dev/null
+++ b/snippet_repository_storage_move.go
@@ -0,0 +1,203 @@
+//
+// Copyright 2023, Nick Westbury
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"time"
+)
+
+// SnippetRepositoryStorageMoveService handles communication with the
+// snippets related methods of the GitLab API.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html
+type SnippetRepositoryStorageMoveService struct {
+	client *Client
+}
+
+// SnippetRepositoryStorageMove represents the status of a repository move.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html
+type SnippetRepositoryStorageMove struct {
+	ID                     int                `json:"id"`
+	CreatedAt              *time.Time         `json:"created_at"`
+	State                  string             `json:"state"`
+	SourceStorageName      string             `json:"source_storage_name"`
+	DestinationStorageName string             `json:"destination_storage_name"`
+	Snippet                *RepositorySnippet `json:"snippet"`
+}
+
+type RepositorySnippet struct {
+	ID            int             `json:"id"`
+	Title         string          `json:"title"`
+	Description   string          `json:"description"`
+	Visibility    VisibilityValue `json:"visibility"`
+	UpdatedAt     *time.Time      `json:"updated_at"`
+	CreatedAt     *time.Time      `json:"created_at"`
+	ProjectID     int             `json:"project_id"`
+	WebURL        string          `json:"web_url"`
+	RawURL        string          `json:"raw_url"`
+	SSHURLToRepo  string          `json:"ssh_url_to_repo"`
+	HTTPURLToRepo string          `json:"http_url_to_repo"`
+}
+
+// RetrieveAllSnippetStorageMovesOptions represents the available
+// RetrieveAllStorageMoves() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html
+type RetrieveAllSnippetStorageMovesOptions ListOptions
+
+// RetrieveAllStorageMoves retrieves all snippet repository storage moves
+// accessible by the authenticated user.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#retrieve-all-repository-storage-moves-for-a-snippet
+func (s SnippetRepositoryStorageMoveService) RetrieveAllStorageMoves(opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) {
+	req, err := s.client.NewRequest(http.MethodGet, "snippet_repository_storage_moves", opts, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var ssms []*SnippetRepositoryStorageMove
+	resp, err := s.client.Do(req, &ssms)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return ssms, resp, err
+}
+
+// RetrieveAllStorageMovesForSnippet retrieves all repository storage moves for
+// a single snippet accessible by the authenticated user.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#retrieve-all-repository-storage-moves-for-a-snippet
+func (s SnippetRepositoryStorageMoveService) RetrieveAllStorageMovesForSnippet(snippet int, opts RetrieveAllSnippetStorageMovesOptions, options ...RequestOptionFunc) ([]*SnippetRepositoryStorageMove, *Response, error) {
+	u := fmt.Sprintf("snippets/%d/repository_storage_moves", snippet)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, opts, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	var ssms []*SnippetRepositoryStorageMove
+	resp, err := s.client.Do(req, &ssms)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return ssms, resp, err
+}
+
+// GetStorageMove gets a single snippet repository storage move.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#get-a-single-snippet-repository-storage-move
+func (s SnippetRepositoryStorageMoveService) GetStorageMove(repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) {
+	u := fmt.Sprintf("snippet_repository_storage_moves/%d", repositoryStorage)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ssm := new(SnippetRepositoryStorageMove)
+	resp, err := s.client.Do(req, ssm)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return ssm, resp, err
+}
+
+// GetStorageMoveForSnippet gets a single repository storage move for a snippet.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#get-a-single-repository-storage-move-for-a-snippet
+func (s SnippetRepositoryStorageMoveService) GetStorageMoveForSnippet(snippet int, repositoryStorage int, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) {
+	u := fmt.Sprintf("snippets/%d/repository_storage_moves/%d", snippet, repositoryStorage)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ssm := new(SnippetRepositoryStorageMove)
+	resp, err := s.client.Do(req, ssm)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return ssm, resp, err
+}
+
+// ScheduleStorageMoveForSnippetOptions represents the available
+// ScheduleStorageMoveForSnippet() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html
+type ScheduleStorageMoveForSnippetOptions struct {
+	DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"`
+}
+
+// ScheduleStorageMoveForSnippet schedule a repository to be moved for a snippet.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#schedule-a-repository-storage-move-for-a-snippet
+func (s SnippetRepositoryStorageMoveService) ScheduleStorageMoveForSnippet(snippet int, opts ScheduleStorageMoveForSnippetOptions, options ...RequestOptionFunc) (*SnippetRepositoryStorageMove, *Response, error) {
+	u := fmt.Sprintf("snippets/%d/repository_storage_moves", snippet)
+
+	req, err := s.client.NewRequest(http.MethodPost, u, opts, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	ssm := new(SnippetRepositoryStorageMove)
+	resp, err := s.client.Do(req, ssm)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return ssm, resp, err
+}
+
+// ScheduleAllStorageMovesOptions represents the available
+// ScheduleAllStorageMoves() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html
+type ScheduleAllStorageMovesOptions struct {
+	SourceStorageName      *string `url:"source_storage_name,omitempty" json:"source_storage_name,omitempty"`
+	DestinationStorageName *string `url:"destination_storage_name,omitempty" json:"destination_storage_name,omitempty"`
+}
+
+// ScheduleAllStorageMoves schedules all snippet repositories to be moved.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/snippet_repository_storage_moves.html#schedule-repository-storage-moves-for-all-snippets-on-a-storage-shard
+func (s SnippetRepositoryStorageMoveService) ScheduleAllStorageMoves(opts ScheduleAllStorageMovesOptions, options ...RequestOptionFunc) (*Response, error) {
+	req, err := s.client.NewRequest(http.MethodPost, "snippet_repository_storage_moves", opts, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(req, nil)
+}


Test patch:
diff --git a/snippet_repository_storage_move_test.go b/snippet_repository_storage_move_test.go
new file mode 100644
index 0000000..2d1a446
--- /dev/null
+++ b/snippet_repository_storage_move_test.go
@@ -0,0 +1,215 @@
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestSnippetRepositoryStorageMove_RetrieveAllSnippetStorageMoves(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippet_repository_storage_moves", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `[
+		{
+		  "id":123,
+		  "state":"scheduled",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		},
+		{
+		  "id":122,
+		  "state":"finished",
+		  "snippet":{
+			"id":64,
+			"title":"Test Snippet 2"
+		  }
+		}]`)
+	})
+
+	opts := RetrieveAllSnippetStorageMovesOptions{Page: 1, PerPage: 2}
+
+	ssms, _, err := client.SnippetRepositoryStorageMove.RetrieveAllStorageMoves(opts)
+	require.NoError(t, err)
+
+	want := []*SnippetRepositoryStorageMove{
+		{
+			ID:    123,
+			State: "scheduled",
+			Snippet: &RepositorySnippet{
+				ID:    65,
+				Title: "Test Snippet",
+			},
+		},
+		{
+			ID:    122,
+			State: "finished",
+			Snippet: &RepositorySnippet{
+				ID:    64,
+				Title: "Test Snippet 2",
+			},
+		},
+	}
+	require.Equal(t, want, ssms)
+}
+
+func TestSnippetRepositoryStorageMove_RetrieveAllStorageMovesForSnippet(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippets/65/repository_storage_moves", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `[
+		{
+		  "id":123,
+		  "state":"scheduled",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		},
+		{
+		  "id":122,
+		  "state":"finished",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		}]`)
+	})
+
+	opts := RetrieveAllSnippetStorageMovesOptions{Page: 1, PerPage: 2}
+
+	ssms, _, err := client.SnippetRepositoryStorageMove.RetrieveAllStorageMovesForSnippet(65, opts)
+	require.NoError(t, err)
+
+	want := []*SnippetRepositoryStorageMove{
+		{
+			ID:    123,
+			State: "scheduled",
+			Snippet: &RepositorySnippet{
+				ID:    65,
+				Title: "Test Snippet",
+			},
+		},
+		{
+			ID:    122,
+			State: "finished",
+			Snippet: &RepositorySnippet{
+				ID:    65,
+				Title: "Test Snippet",
+			},
+		},
+	}
+	require.Equal(t, want, ssms)
+}
+
+func TestSnippetRepositoryStorageMove_GetStorageMove(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippet_repository_storage_moves/123", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `
+		{
+		  "id":123,
+		  "state":"scheduled",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		}`)
+	})
+
+	ssm, _, err := client.SnippetRepositoryStorageMove.GetStorageMove(123)
+	require.NoError(t, err)
+
+	want := &SnippetRepositoryStorageMove{
+		ID:    123,
+		State: "scheduled",
+		Snippet: &RepositorySnippet{
+			ID:    65,
+			Title: "Test Snippet",
+		},
+	}
+	require.Equal(t, want, ssm)
+}
+
+func TestSnippetRepositoryStorageMove_GetStorageMoveForSnippet(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippets/65/repository_storage_moves/123", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `
+		{
+		  "id":123,
+		  "state":"scheduled",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		}`)
+	})
+
+	ssm, _, err := client.SnippetRepositoryStorageMove.GetStorageMoveForSnippet(65, 123)
+	require.NoError(t, err)
+
+	want := &SnippetRepositoryStorageMove{
+		ID:    123,
+		State: "scheduled",
+		Snippet: &RepositorySnippet{
+			ID:    65,
+			Title: "Test Snippet",
+		},
+	}
+	require.Equal(t, want, ssm)
+}
+
+func TestSnippetRepositoryStorageMove_ScheduleStorageMoveForSnippet(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippets/65/repository_storage_moves", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPost)
+		fmt.Fprint(w, `
+		{
+		  "id":124,
+		  "state":"scheduled",
+		  "snippet":{
+			"id":65,
+			"title":"Test Snippet"
+		  }
+		}`)
+	})
+
+	ssm, _, err := client.SnippetRepositoryStorageMove.ScheduleStorageMoveForSnippet(65, ScheduleStorageMoveForSnippetOptions{})
+	require.NoError(t, err)
+
+	want := &SnippetRepositoryStorageMove{
+		ID:    124,
+		State: "scheduled",
+		Snippet: &RepositorySnippet{
+			ID:    65,
+			Title: "Test Snippet",
+		},
+	}
+	require.Equal(t, want, ssm)
+}
+
+func TestSnippetRepositoryStorageMove_ScheduleAllStorageMoves(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/snippet_repository_storage_moves", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPost)
+		fmt.Fprint(w, `{"message": "202 Accepted"}`)
+	})
+
+	_, err := client.SnippetRepositoryStorageMove.ScheduleAllStorageMoves(
+		ScheduleAllStorageMovesOptions{
+			SourceStorageName: String("default"),
+		},
+	)
+	require.NoError(t, err)
+}