package stacks import ( "net/http" "net/http/httptest" "os" "path/filepath" "strconv" "testing" portainer "github.com/portainer/portainer/api" "github.com/portainer/portainer/api/datastore" "github.com/portainer/portainer/api/filesystem" gittypes "github.com/portainer/portainer/api/git/types" "github.com/portainer/portainer/api/internal/testhelpers" "encoding/json" "github.com/stretchr/testify/require" ) func TestStackFile_GitPendingRedeploy_Returns409(t *testing.T) { _, store := datastore.MustNewTestStore(t, true, true) _, err := mockCreateUser(store) require.NoError(t, err) endpoint, err := mockCreateEndpoint(store) require.NoError(t, err) tempDir := t.TempDir() fileService, err := filesystem.NewService(tempDir, "") require.NoError(t, err) handler := NewHandler(testhelpers.NewTestRequestBouncer()) handler.FileService = fileService handler.DataStore = store stack := &portainer.Stack{ ID: 1, EndpointID: endpoint.ID, Type: portainer.DockerComposeStack, CurrentDeploymentInfo: &portainer.StackDeploymentInfo{ RepositoryURL: "https://github.com/portainer/old-repo.git", ConfigFilePath: "docker-compose.yml", }, GitConfig: &gittypes.RepoConfig{ URL: "https://github.com/portainer/portainer.git", ConfigFilePath: "docker-compose.yml", }, } require.NoError(t, store.Stack().Create(stack)) req := mockCreateStackRequestWithSecurityContext( http.MethodGet, "/stacks/"+strconv.Itoa(int(stack.ID))+"/file", nil, ) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) require.Equal(t, http.StatusConflict, rr.Code) } func TestStackFile_MatchingGitSettings_ReturnsFileContent(t *testing.T) { _, store := datastore.MustNewTestStore(t, true, true) _, err := mockCreateUser(store) require.NoError(t, err) endpoint, err := mockCreateEndpoint(store) require.NoError(t, err) tempDir := t.TempDir() fileService, err := filesystem.NewService(tempDir, "") require.NoError(t, err) handler := NewHandler(testhelpers.NewTestRequestBouncer()) handler.FileService = fileService handler.DataStore = store const repoURL = "https://github.com/portainer/portainer.git" const configPath = "docker-compose.yml" const fileContent = "version: '3'\nservices:\n web:\n image: nginx\n" require.NoError(t, os.WriteFile(filepath.Join(tempDir, configPath), []byte(fileContent), 0o644)) stack := &portainer.Stack{ ID: 2, EndpointID: endpoint.ID, Type: portainer.DockerComposeStack, ProjectPath: tempDir, EntryPoint: configPath, CurrentDeploymentInfo: &portainer.StackDeploymentInfo{ RepositoryURL: repoURL, ConfigFilePath: configPath, }, GitConfig: &gittypes.RepoConfig{ URL: repoURL, ConfigFilePath: configPath, }, } require.NoError(t, store.Stack().Create(stack)) req := mockCreateStackRequestWithSecurityContext( http.MethodGet, "/stacks/"+strconv.Itoa(int(stack.ID))+"/file", nil, ) rr := httptest.NewRecorder() handler.ServeHTTP(rr, req) require.Equal(t, http.StatusOK, rr.Code) var resp stackFileResponse require.NoError(t, json.Unmarshal(rr.Body.Bytes(), &resp)) require.Equal(t, fileContent, resp.StackFileContent) }