Verified Commit 9a42d02e authored by Zubeen's avatar Zubeen 🤖 Committed by GitLab
Browse files

feat(resource_group): add endpoint to get the current job of a resource group

Changelog: Improvements
parent 95be8ccf
Loading
Loading
Loading
Loading
+14 −0
Changes for resource_group.go: 14 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ var (
	routeProjectsIDResourceGroups               = route("projects/%s/resource_groups")
	routeProjectsIDResourceGroupsID             = route("projects/%s/resource_groups/%s")
	routeProjectsIDResourceGroupsIDUpcomingJobs = route("projects/%s/resource_groups/%s/upcoming_jobs")
	routeProjectsIDResourceGroupsIDCurrentJob   = route("projects/%s/resource_groups/%s/current_job")
)

type (
@@ -32,6 +33,7 @@ type (
		GetAllResourceGroupsForAProject(pid any, options ...RequestOptionFunc) ([]*ResourceGroup, *Response, error)
		GetASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) (*ResourceGroup, *Response, error)
		ListUpcomingJobsForASpecificResourceGroup(pid any, key string, options ...RequestOptionFunc) ([]*Job, *Response, error)
		GetCurrentJobForAResourceGroup(pid any, key string, options ...RequestOptionFunc) (*Job, *Response, error)
		EditAnExistingResourceGroup(pid any, key string, opts *EditAnExistingResourceGroupOptions, options ...RequestOptionFunc) (*ResourceGroup, *Response, error)
	}

@@ -103,6 +105,18 @@ func (s *ResourceGroupService) ListUpcomingJobsForASpecificResourceGroup(pid any
	)
}

// GetCurrentJobForAResourceGroup allows you to get the job that currently
// holds the lock of a specific resource group for a given project.
//
// GitLab API docs:
// https://docs.gitlab.com/api/resource_groups/#retrieve-current-job-for-a-resource-group
func (s *ResourceGroupService) GetCurrentJobForAResourceGroup(pid any, key string, options ...RequestOptionFunc) (*Job, *Response, error) {
	return do[*Job](s.client,
		withPath(routeProjectsIDResourceGroupsIDCurrentJob, ProjectID{pid}, key),
		withRequestOpts(options...),
	)
}

// EditAnExistingResourceGroupOptions represents the available
// EditAnExistingResourceGroup options.
//
+77 −0
Changes for resource_group_test.go: 77 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

@@ -140,6 +141,82 @@ func TestResourceGroups_ListUpcomingJobsForASpecificResourceGroup(t *testing.T)
	require.Nil(t, jobs)
}

func TestResourceGroups_GetCurrentJobForAResourceGroup(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	// GIVEN a project with a current job on the production resource group
	mux.HandleFunc("/api/v4/projects/1/resource_groups/production/current_job", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprint(w, `{
			"id": 1154,
			"status": "waiting_for_resource",
			"stage": "deploy",
			"name": "deploy_to_production",
			"ref": "main"
		}`)
	})

	want := &Job{
		ID:     1154,
		Status: "waiting_for_resource",
		Stage:  "deploy",
		Name:   "deploy_to_production",
		Ref:    "main",
	}

	// WHEN the current job is requested
	job, resp, err := client.ResourceGroup.GetCurrentJobForAResourceGroup(1, "production")

	// THEN the job is returned
	require.NoError(t, err)
	assert.NotNil(t, resp)
	assert.Equal(t, want, job)
}

func TestResourceGroups_GetCurrentJobForAResourceGroup_InvalidIDType(t *testing.T) {
	t.Parallel()
	_, client := setup(t)

	// GIVEN a project ID of an unsupported type
	// WHEN the current job is requested
	job, resp, err := client.ResourceGroup.GetCurrentJobForAResourceGroup(1.01, "production")

	// THEN an invalid ID type error is returned
	assert.ErrorIs(t, err, ErrInvalidIDType)
	assert.Nil(t, resp)
	assert.Nil(t, job)
}

func TestResourceGroups_GetCurrentJobForAResourceGroup_RequestOptionError(t *testing.T) {
	t.Parallel()
	_, client := setup(t)

	// GIVEN a request option that fails
	// WHEN the current job is requested
	job, resp, err := client.ResourceGroup.GetCurrentJobForAResourceGroup(1, "production", errorOption)

	// THEN the request option error is returned
	assert.ErrorIs(t, err, errRequestOptionFunc)
	assert.Nil(t, resp)
	assert.Nil(t, job)
}

func TestResourceGroups_GetCurrentJobForAResourceGroup_NotFound(t *testing.T) {
	t.Parallel()
	_, client := setup(t)

	// GIVEN a project that has no matching endpoint
	// WHEN the current job is requested
	job, resp, err := client.ResourceGroup.GetCurrentJobForAResourceGroup(2, "production")

	// THEN a 404 error is returned
	require.Error(t, err)
	require.NotNil(t, resp)
	assert.Equal(t, http.StatusNotFound, resp.StatusCode)
	assert.Nil(t, job)
}

func TestResourceGroup_EditAnExistingResourceGroup(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)
+45 −0
Changes for testing/resource_group_mock.go: 45 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -174,6 +174,51 @@ func (c *MockResourceGroupServiceInterfaceGetAllResourceGroupsForAProjectCall) D
	return c
}

// GetCurrentJobForAResourceGroup mocks base method.
func (m *MockResourceGroupServiceInterface) GetCurrentJobForAResourceGroup(pid any, key string, options ...gitlab.RequestOptionFunc) (*gitlab.Job, *gitlab.Response, error) {
	m.ctrl.T.Helper()
	varargs := []any{pid, key}
	for _, a := range options {
		varargs = append(varargs, a)
	}
	ret := m.ctrl.Call(m, "GetCurrentJobForAResourceGroup", varargs...)
	ret0, _ := ret[0].(*gitlab.Job)
	ret1, _ := ret[1].(*gitlab.Response)
	ret2, _ := ret[2].(error)
	return ret0, ret1, ret2
}

// GetCurrentJobForAResourceGroup indicates an expected call of GetCurrentJobForAResourceGroup.
func (mr *MockResourceGroupServiceInterfaceMockRecorder) GetCurrentJobForAResourceGroup(pid, key any, options ...any) *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall {
	mr.mock.ctrl.T.Helper()
	varargs := append([]any{pid, key}, options...)
	call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentJobForAResourceGroup", reflect.TypeOf((*MockResourceGroupServiceInterface)(nil).GetCurrentJobForAResourceGroup), varargs...)
	return &MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall{Call: call}
}

// MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall wrap *gomock.Call
type MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall struct {
	*gomock.Call
}

// Return rewrite *gomock.Call.Return
func (c *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall) Return(arg0 *gitlab.Job, arg1 *gitlab.Response, arg2 error) *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall {
	c.Call = c.Call.Return(arg0, arg1, arg2)
	return c
}

// Do rewrite *gomock.Call.Do
func (c *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall) Do(f func(any, string, ...gitlab.RequestOptionFunc) (*gitlab.Job, *gitlab.Response, error)) *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall {
	c.Call = c.Call.Do(f)
	return c
}

// DoAndReturn rewrite *gomock.Call.DoAndReturn
func (c *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall) DoAndReturn(f func(any, string, ...gitlab.RequestOptionFunc) (*gitlab.Job, *gitlab.Response, error)) *MockResourceGroupServiceInterfaceGetCurrentJobForAResourceGroupCall {
	c.Call = c.Call.DoAndReturn(f)
	return c
}

// ListUpcomingJobsForASpecificResourceGroup mocks base method.
func (m *MockResourceGroupServiceInterface) ListUpcomingJobsForASpecificResourceGroup(pid any, key string, options ...gitlab.RequestOptionFunc) ([]*gitlab.Job, *gitlab.Response, error) {
	m.ctrl.T.Helper()