package controllers_test import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" . "github.com/petergtz/pegomock/v4" "github.com/runatlantis/atlantis/server/controllers" . "github.com/runatlantis/atlantis/server/core/locking/mocks" "github.com/runatlantis/atlantis/server/events" "github.com/runatlantis/atlantis/server/events/command" . "github.com/runatlantis/atlantis/server/events/mocks" "github.com/runatlantis/atlantis/server/events/models" . "github.com/runatlantis/atlantis/server/events/vcs/mocks" "github.com/runatlantis/atlantis/server/logging" "github.com/runatlantis/atlantis/server/metrics" . "github.com/runatlantis/atlantis/testing" ) const atlantisTokenHeader = "X-Atlantis-Token" const atlantisToken = "token" func TestAPIController_Plan(t *testing.T) { ac, projectCommandBuilder, projectCommandRunner := setup(t) body, _ := json.Marshal(controllers.APIRequest{ Repository: "Repo", Ref: "main", Type: "Gitlab", Projects: []string{"default"}, }) req, _ := http.NewRequest("POST", "", bytes.NewBuffer(body)) req.Header.Set(atlantisTokenHeader, atlantisToken) w := httptest.NewRecorder() ac.Plan(w, req) ResponseContains(t, w, http.StatusOK, "") projectCommandBuilder.VerifyWasCalledOnce().BuildPlanCommands(Any[*command.Context](), Any[*events.CommentCommand]()) projectCommandRunner.VerifyWasCalledOnce().Plan(Any[command.ProjectContext]()) } func TestAPIController_Apply(t *testing.T) { ac, projectCommandBuilder, projectCommandRunner := setup(t) body, _ := json.Marshal(controllers.APIRequest{ Repository: "Repo", Ref: "main", Type: "Gitlab", Projects: []string{"default"}, }) req, _ := http.NewRequest("POST", "", bytes.NewBuffer(body)) req.Header.Set(atlantisTokenHeader, atlantisToken) w := httptest.NewRecorder() ac.Apply(w, req) ResponseContains(t, w, http.StatusOK, "") projectCommandBuilder.VerifyWasCalledOnce().BuildApplyCommands(Any[*command.Context](), Any[*events.CommentCommand]()) projectCommandRunner.VerifyWasCalledOnce().Plan(Any[command.ProjectContext]()) projectCommandRunner.VerifyWasCalledOnce().Apply(Any[command.ProjectContext]()) } func setup(t *testing.T) (controllers.APIController, *MockProjectCommandBuilder, *MockProjectCommandRunner) { RegisterMockTestingT(t) locker := NewMockLocker() logger := logging.NewNoopLogger(t) scope, _, _ := metrics.NewLoggingScope(logger, "null") parser := NewMockEventParsing() vcsClient := NewMockClient() repoAllowlistChecker, err := events.NewRepoAllowlistChecker("*") Ok(t, err) projectCommandBuilder := NewMockProjectCommandBuilder() When(projectCommandBuilder.BuildPlanCommands(Any[*command.Context](), Any[*events.CommentCommand]())). ThenReturn([]command.ProjectContext{{ CommandName: command.Plan, }}, nil) When(projectCommandBuilder.BuildApplyCommands(Any[*command.Context](), Any[*events.CommentCommand]())). ThenReturn([]command.ProjectContext{{ CommandName: command.Apply, }}, nil) projectCommandRunner := NewMockProjectCommandRunner() When(projectCommandRunner.Plan(Any[command.ProjectContext]())).ThenReturn(command.ProjectResult{ PlanSuccess: &models.PlanSuccess{}, }) When(projectCommandRunner.Apply(Any[command.ProjectContext]())).ThenReturn(command.ProjectResult{ ApplySuccess: "success", }) preWorkflowHooksCommandRunner := NewMockPreWorkflowHooksCommandRunner() When(preWorkflowHooksCommandRunner.RunPreHooks(Any[*command.Context](), Any[*events.CommentCommand]())).ThenReturn(nil) postWorkflowHooksCommandRunner := NewMockPostWorkflowHooksCommandRunner() When(postWorkflowHooksCommandRunner.RunPostHooks(Any[*command.Context](), Any[*events.CommentCommand]())).ThenReturn(nil) ac := controllers.APIController{ APISecret: []byte(atlantisToken), Locker: locker, Logger: logger, Scope: scope, Parser: parser, ProjectCommandBuilder: projectCommandBuilder, ProjectPlanCommandRunner: projectCommandRunner, ProjectApplyCommandRunner: projectCommandRunner, PreWorkflowHooksCommandRunner: preWorkflowHooksCommandRunner, PostWorkflowHooksCommandRunner: postWorkflowHooksCommandRunner, VCSClient: vcsClient, RepoAllowlistChecker: repoAllowlistChecker, } return ac, projectCommandBuilder, projectCommandRunner }