diff --git a/models/actions/variable.go b/models/actions/variable.go index 203065487c..34fef60839 100644 --- a/models/actions/variable.go +++ b/models/actions/variable.go @@ -81,6 +81,14 @@ func (opts FindVariablesOpts) ToConds() builder.Cond { return cond } +var _ db.FindOptionsOrder = FindVariablesOpts{} + +// ToOrders implements db.FindOptionsOrder to have a stable sort order +func (opts FindVariablesOpts) ToOrders() string { + // Sort by name. ID serves as a tie-breaker. + return "name, id" +} + func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*ActionVariable, error) { return db.Find[ActionVariable](ctx, opts) } diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go index 716a0b7fdb..9a0dbf1f28 100644 --- a/routers/api/v1/repo/action.go +++ b/routers/api/v1/repo/action.go @@ -472,6 +472,7 @@ func (Action) ListVariables(ctx *context.APIContext) { OwnerID: v.OwnerID, RepoID: v.RepoID, Name: v.Name, + Data: v.Data, } } diff --git a/tests/integration/api_org_variables_test.go b/tests/integration/api_org_variables_test.go new file mode 100644 index 0000000000..ffd73fadb2 --- /dev/null +++ b/tests/integration/api_org_variables_test.go @@ -0,0 +1,231 @@ +// Copyright 2025 The Forgejo Authors. All rights reserved. +// SPDX-License-Identifier: GPL-3.0-or-later + +package integration + +import ( + "fmt" + "net/http" + "testing" + + auth_model "forgejo.org/models/auth" + org_model "forgejo.org/models/organization" + "forgejo.org/models/unittest" + api "forgejo.org/modules/structs" + "forgejo.org/tests" + + "github.com/stretchr/testify/assert" +) + +func TestAPIOrgVariablesCreateOrganizationVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"}) + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + cases := []struct { + Name string + ExpectedStatus int + }{ + { + Name: "-", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "_", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "TEST_VAR", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "test_var", + ExpectedStatus: http.StatusConflict, + }, + { + Name: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "123var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "var@test", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "github_var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "gitea_var", + ExpectedStatus: http.StatusBadRequest, + }, + } + + for _, c := range cases { + requestURL := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, c.Name) + request := NewRequestWithJSON(t, "POST", requestURL, api.CreateVariableOption{Value: "value"}) + request.AddTokenAuth(token) + MakeRequest(t, request, c.ExpectedStatus) + } +} + +func TestAPIOrgVariablesUpdateOrganizationVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"}) + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + variableName := "test_update_var" + + url := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, variableName) + + request := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{Value: "initial_val"}) + request.AddTokenAuth(token) + + MakeRequest(t, request, http.StatusNoContent) + + cases := []struct { + Name string + UpdateName string + ExpectedStatus int + }{ + { + Name: "not_found_var", + ExpectedStatus: http.StatusNotFound, + }, + { + Name: variableName, + UpdateName: "1invalid", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "invalid@name", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: variableName, + ExpectedStatus: http.StatusNotFound, + }, + { + Name: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + } + + for _, c := range cases { + url := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, c.Name) + request := NewRequestWithJSON(t, "PUT", url, api.UpdateVariableOption{Name: c.UpdateName, Value: "updated_val"}) + request.AddTokenAuth(token) + MakeRequest(t, request, c.ExpectedStatus) + } +} + +func TestAPIOrgVariablesDeleteOrganizationVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"}) + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + variableName := "test_delete_var" + + url := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, variableName) + + request := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{Value: "initial_val"}) + request.AddTokenAuth(token) + MakeRequest(t, request, http.StatusNoContent) + + request = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, request, http.StatusNoContent) + + request = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, request, http.StatusNotFound) +} + +func TestAPIOrgVariablesGetSingleOrganizationVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"}) + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + name := "some_variable" + value := "false" + + createURL := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, name) + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: value}) + createRequest.AddTokenAuth(token) + MakeRequest(t, createRequest, http.StatusNoContent) + + getURL := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, name) + + getRequest := NewRequest(t, "GET", getURL) + getRequest.AddTokenAuth(token) + getResponse := MakeRequest(t, getRequest, http.StatusOK) + + var actionVariable api.ActionVariable + DecodeJSON(t, getResponse, &actionVariable) + + assert.NotNil(t, actionVariable) + assert.Equal(t, org.ID, actionVariable.OwnerID) + assert.Equal(t, int64(0), actionVariable.RepoID) + assert.Equal(t, "SOME_VARIABLE", actionVariable.Name) + assert.Equal(t, value, actionVariable.Data) +} + +func TestAPIOrgVariablesGetAllOrganizationVariables(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + org := unittest.AssertExistsAndLoadBean(t, &org_model.Organization{Name: "org3"}) + session := loginUser(t, "user2") + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization) + + variables := map[string]string{"second": "Dolor sit amet", "first": "Lorem ipsum"} + for name, value := range variables { + createURL := fmt.Sprintf("/api/v1/orgs/%s/actions/variables/%s", org.Name, name) + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: value}) + createRequest.AddTokenAuth(token) + + MakeRequest(t, createRequest, http.StatusNoContent) + } + + getURL := fmt.Sprintf("/api/v1/orgs/%s/actions/variables", org.Name) + + getRequest := NewRequest(t, "GET", getURL) + getRequest.AddTokenAuth(token) + getResponse := MakeRequest(t, getRequest, http.StatusOK) + + var actionVariables []api.ActionVariable + DecodeJSON(t, getResponse, &actionVariables) + + assert.Len(t, actionVariables, len(variables)) + + assert.Equal(t, org.ID, actionVariables[0].OwnerID) + assert.Equal(t, int64(0), actionVariables[0].RepoID) + assert.Equal(t, "FIRST", actionVariables[0].Name) + assert.Equal(t, "Lorem ipsum", actionVariables[0].Data) + + assert.Equal(t, org.ID, actionVariables[1].OwnerID) + assert.Equal(t, int64(0), actionVariables[1].RepoID) + assert.Equal(t, "SECOND", actionVariables[1].Name) + assert.Equal(t, "Dolor sit amet", actionVariables[1].Data) +} diff --git a/tests/integration/api_repo_variables_test.go b/tests/integration/api_repo_variables_test.go index 6e3e8c1db6..27401dcdd3 100644 --- a/tests/integration/api_repo_variables_test.go +++ b/tests/integration/api_repo_variables_test.go @@ -14,9 +14,11 @@ import ( user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" "forgejo.org/tests" + + "github.com/stretchr/testify/assert" ) -func TestAPIRepoVariables(t *testing.T) { +func TestAPIRepoVariablesTestCreateRepositoryVariable(t *testing.T) { defer tests.PrepareTestEnv(t)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) @@ -24,126 +26,211 @@ func TestAPIRepoVariables(t *testing.T) { session := loginUser(t, user.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) - t.Run("CreateRepoVariable", func(t *testing.T) { - cases := []struct { - Name string - ExpectedStatus int - }{ - { - Name: "-", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "_", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: "TEST_VAR", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: "test_var", - ExpectedStatus: http.StatusConflict, - }, - { - Name: "ci", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "123var", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "var@test", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "github_var", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "gitea_var", - ExpectedStatus: http.StatusBadRequest, - }, - } + cases := []struct { + Name string + ExpectedStatus int + }{ + { + Name: "-", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "_", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "TEST_VAR", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "test_var", + ExpectedStatus: http.StatusConflict, + }, + { + Name: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "123var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "var@test", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "github_var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "gitea_var", + ExpectedStatus: http.StatusBadRequest, + }, + } - for _, c := range cases { - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), c.Name), api.CreateVariableOption{ - Value: "value", - }).AddTokenAuth(token) - MakeRequest(t, req, c.ExpectedStatus) - } - }) - - t.Run("UpdateRepoVariable", func(t *testing.T) { - variableName := "test_update_var" - url := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), variableName) - req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ - Value: "initial_val", + for _, c := range cases { + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), c.Name), api.CreateVariableOption{ + Value: "value", }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - cases := []struct { - Name string - UpdateName string - ExpectedStatus int - }{ - { - Name: "not_found_var", - ExpectedStatus: http.StatusNotFound, - }, - { - Name: variableName, - UpdateName: "1invalid", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "invalid@name", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "ci", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "updated_var_name", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: variableName, - ExpectedStatus: http.StatusNotFound, - }, - { - Name: "updated_var_name", - ExpectedStatus: http.StatusNoContent, - }, - } - - for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), c.Name), api.UpdateVariableOption{ - Name: c.UpdateName, - Value: "updated_val", - }).AddTokenAuth(token) - MakeRequest(t, req, c.ExpectedStatus) - } - }) - - t.Run("DeleteRepoVariable", func(t *testing.T) { - variableName := "test_delete_var" - url := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), variableName) - - req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ - Value: "initial_val", - }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - req = NewRequest(t, "DELETE", url).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - req = NewRequest(t, "DELETE", url).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNotFound) - }) + MakeRequest(t, req, c.ExpectedStatus) + } +} + +func TestAPIRepoVariablesUpdateRepositoryVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + variableName := "test_update_var" + url := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), variableName) + req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ + Value: "initial_val", + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + cases := []struct { + Name string + UpdateName string + ExpectedStatus int + }{ + { + Name: "not_found_var", + ExpectedStatus: http.StatusNotFound, + }, + { + Name: variableName, + UpdateName: "1invalid", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "invalid@name", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: variableName, + ExpectedStatus: http.StatusNotFound, + }, + { + Name: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + } + + for _, c := range cases { + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), c.Name), api.UpdateVariableOption{ + Name: c.UpdateName, + Value: "updated_val", + }).AddTokenAuth(token) + MakeRequest(t, req, c.ExpectedStatus) + } +} + +func TestAPIRepoVariablesDeleteRepositoryVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + variableName := "test_delete_var" + url := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), variableName) + + req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ + Value: "initial_val", + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNotFound) +} + +func TestAPIRepoVariablesGetSingleRepositoryVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + name := "some_variable" + value := "false" + + createURL := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), name) + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: value}) + createRequest.AddTokenAuth(token) + MakeRequest(t, createRequest, http.StatusNoContent) + + getURL := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), name) + + getRequest := NewRequest(t, "GET", getURL) + getRequest.AddTokenAuth(token) + getResponse := MakeRequest(t, getRequest, http.StatusOK) + + var actionVariable api.ActionVariable + DecodeJSON(t, getResponse, &actionVariable) + + assert.NotNil(t, actionVariable) + assert.Equal(t, int64(0), actionVariable.OwnerID) + assert.Equal(t, repo.ID, actionVariable.RepoID) + assert.Equal(t, "SOME_VARIABLE", actionVariable.Name) + assert.Equal(t, value, actionVariable.Data) +} + +func TestAPIRepoVariablesGetAllRepositoryVariables(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) + session := loginUser(t, user.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) + + variables := map[string]string{"second": "Dolor sit amet", "first": "Lorem ipsum"} + for name, value := range variables { + createURL := fmt.Sprintf("/api/v1/repos/%s/actions/variables/%s", repo.FullName(), name) + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: value}) + createRequest.AddTokenAuth(token) + + MakeRequest(t, createRequest, http.StatusNoContent) + } + + getURL := fmt.Sprintf("/api/v1/repos/%s/actions/variables", repo.FullName()) + + getRequest := NewRequest(t, "GET", getURL) + getRequest.AddTokenAuth(token) + getResponse := MakeRequest(t, getRequest, http.StatusOK) + + var actionVariables []api.ActionVariable + DecodeJSON(t, getResponse, &actionVariables) + + assert.Len(t, actionVariables, len(variables)) + + assert.Equal(t, int64(0), actionVariables[0].OwnerID) + assert.Equal(t, repo.ID, actionVariables[0].RepoID) + assert.Equal(t, "FIRST", actionVariables[0].Name) + assert.Equal(t, "Lorem ipsum", actionVariables[0].Data) + + assert.Equal(t, int64(0), actionVariables[1].OwnerID) + assert.Equal(t, repo.ID, actionVariables[1].RepoID) + assert.Equal(t, "SECOND", actionVariables[1].Name) + assert.Equal(t, "Dolor sit amet", actionVariables[1].Data) } diff --git a/tests/integration/api_user_variables_test.go b/tests/integration/api_user_variables_test.go index 2e219be7ec..12b4cb5b55 100644 --- a/tests/integration/api_user_variables_test.go +++ b/tests/integration/api_user_variables_test.go @@ -9,136 +9,224 @@ import ( "testing" auth_model "forgejo.org/models/auth" + "forgejo.org/models/unittest" + user_model "forgejo.org/models/user" api "forgejo.org/modules/structs" "forgejo.org/tests" + + "github.com/stretchr/testify/assert" ) -func TestAPIUserVariables(t *testing.T) { +func TestAPIUserVariablesCreateUserVariable(t *testing.T) { defer tests.PrepareTestEnv(t)() - session := loginUser(t, "user1") + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + + session := loginUser(t, user1.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) - t.Run("CreateUserVariable", func(t *testing.T) { - cases := []struct { - Name string - ExpectedStatus int - }{ - { - Name: "-", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "_", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: "TEST_VAR", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: "test_var", - ExpectedStatus: http.StatusConflict, - }, - { - Name: "ci", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "123var", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "var@test", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "github_var", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: "gitea_var", - ExpectedStatus: http.StatusBadRequest, - }, - } + cases := []struct { + Name string + ExpectedStatus int + }{ + { + Name: "-", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "_", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "TEST_VAR", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: "test_var", + ExpectedStatus: http.StatusConflict, + }, + { + Name: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "123var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "var@test", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "github_var", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: "gitea_var", + ExpectedStatus: http.StatusBadRequest, + }, + } - for _, c := range cases { - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.CreateVariableOption{ - Value: "value", - }).AddTokenAuth(token) - MakeRequest(t, req, c.ExpectedStatus) - } - }) - - t.Run("UpdateUserVariable", func(t *testing.T) { - variableName := "test_update_var" - url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) - req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ - Value: "initial_val", + for _, c := range cases { + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.CreateVariableOption{ + Value: "value", }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - cases := []struct { - Name string - UpdateName string - ExpectedStatus int - }{ - { - Name: "not_found_var", - ExpectedStatus: http.StatusNotFound, - }, - { - Name: variableName, - UpdateName: "1invalid", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "invalid@name", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "ci", - ExpectedStatus: http.StatusBadRequest, - }, - { - Name: variableName, - UpdateName: "updated_var_name", - ExpectedStatus: http.StatusNoContent, - }, - { - Name: variableName, - ExpectedStatus: http.StatusNotFound, - }, - { - Name: "updated_var_name", - ExpectedStatus: http.StatusNoContent, - }, - } - - for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.UpdateVariableOption{ - Name: c.UpdateName, - Value: "updated_val", - }).AddTokenAuth(token) - MakeRequest(t, req, c.ExpectedStatus) - } - }) - - t.Run("DeleteRepoVariable", func(t *testing.T) { - variableName := "test_delete_var" - url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) - - req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ - Value: "initial_val", - }).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - req = NewRequest(t, "DELETE", url).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNoContent) - - req = NewRequest(t, "DELETE", url).AddTokenAuth(token) - MakeRequest(t, req, http.StatusNotFound) - }) + MakeRequest(t, req, c.ExpectedStatus) + } +} + +func TestAPIUserVariablesUpdateUserVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + + session := loginUser(t, user1.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + variableName := "test_update_var" + url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) + req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ + Value: "initial_val", + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + cases := []struct { + Name string + UpdateName string + ExpectedStatus int + }{ + { + Name: "not_found_var", + ExpectedStatus: http.StatusNotFound, + }, + { + Name: variableName, + UpdateName: "1invalid", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "invalid@name", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "ci", + ExpectedStatus: http.StatusBadRequest, + }, + { + Name: variableName, + UpdateName: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + { + Name: variableName, + ExpectedStatus: http.StatusNotFound, + }, + { + Name: "updated_var_name", + ExpectedStatus: http.StatusNoContent, + }, + } + + for _, c := range cases { + req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.UpdateVariableOption{ + Name: c.UpdateName, + Value: "updated_val", + }).AddTokenAuth(token) + MakeRequest(t, req, c.ExpectedStatus) + } +} + +func TestAPIUserVariablesDeleteUserVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + + session := loginUser(t, user1.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + variableName := "test_delete_var" + url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) + + req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ + Value: "initial_val", + }).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNoContent) + + req = NewRequest(t, "DELETE", url).AddTokenAuth(token) + MakeRequest(t, req, http.StatusNotFound) +} + +func TestAPIUserVariablesGetSingleUserVariable(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + + session := loginUser(t, user1.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + createURL := fmt.Sprintf("/api/v1/user/actions/variables/%s", "some_variable") + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: "true"}) + createRequest.AddTokenAuth(token) + + MakeRequest(t, createRequest, http.StatusNoContent) + + variableRequest := NewRequest(t, "GET", "/api/v1/user/actions/variables/some_variable") + variableRequest.AddTokenAuth(token) + + variableResponse := MakeRequest(t, variableRequest, http.StatusOK) + + var actionVariable api.ActionVariable + DecodeJSON(t, variableResponse, &actionVariable) + + assert.NotNil(t, actionVariable) + + assert.Equal(t, user1.ID, actionVariable.OwnerID) + assert.Equal(t, int64(0), actionVariable.RepoID) + assert.Equal(t, "SOME_VARIABLE", actionVariable.Name) + assert.Equal(t, "true", actionVariable.Data) +} + +func TestAPIUserVariablesGetAllUserVariables(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) + + session := loginUser(t, user1.Name) + token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser) + + variables := map[string]string{"second": "Dolor sit amet", "first": "Lorem ipsum"} + for name, value := range variables { + createURL := fmt.Sprintf("/api/v1/user/actions/variables/%s", name) + + createRequest := NewRequestWithJSON(t, "POST", createURL, api.CreateVariableOption{Value: value}) + createRequest.AddTokenAuth(token) + + MakeRequest(t, createRequest, http.StatusNoContent) + } + + listRequest := NewRequest(t, "GET", "/api/v1/user/actions/variables") + listRequest.AddTokenAuth(token) + + listResponse := MakeRequest(t, listRequest, http.StatusOK) + + var actionVariables []api.ActionVariable + DecodeJSON(t, listResponse, &actionVariables) + + assert.Len(t, actionVariables, len(variables)) + + assert.Equal(t, user1.ID, actionVariables[0].OwnerID) + assert.Equal(t, int64(0), actionVariables[0].RepoID) + assert.Equal(t, "FIRST", actionVariables[0].Name) + assert.Equal(t, "Lorem ipsum", actionVariables[0].Data) + + assert.Equal(t, user1.ID, actionVariables[1].OwnerID) + assert.Equal(t, int64(0), actionVariables[1].RepoID) + assert.Equal(t, "SECOND", actionVariables[1].Name) + assert.Equal(t, "Dolor sit amet", actionVariables[1].Data) }