Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions command/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ logged in system. non-production server to login to (values are 'pre',
enumflag.New(&selectedRelease, "release", ScratchReleaseIds, enumflag.EnumCaseInsensitive),
"release",
"Salesforce release for scratch org: preview (next release) or previous")
scratchCmd.Flags().Int("duration", 7, "number of days before the scratch org expires (1-30)")

loginCmd.AddCommand(scratchCmd)
RootCmd.AddCommand(loginCmd)
Expand Down Expand Up @@ -219,7 +220,8 @@ Examples:
force login scratch --product communities
force login scratch --product healthcloud
force login scratch --release preview
force login scratch --release previous`,
force login scratch --release previous
force login scratch --duration 14`,
Run: func(cmd *cobra.Command, args []string) {
scratchUser, _ := cmd.Flags().GetString("username")
scratchNamespace, _ := cmd.Flags().GetString("namespace")
Expand All @@ -228,7 +230,8 @@ Examples:
edition := ScratchEditionIds[selectedEdition][0]
allSettings := expandProductsToSettings(selectedProducts, selectedSettings)
release := ScratchReleaseIds[selectedRelease][0]
scratchLogin(scratchUser, allFeatures, edition, allSettings, scratchNamespace, release)
duration, _ := cmd.Flags().GetInt("duration")
scratchLogin(scratchUser, allFeatures, edition, allSettings, scratchNamespace, release, duration)
},
}

Expand Down Expand Up @@ -355,8 +358,8 @@ func expandProductsToSettings(products []ScratchProduct, settings []ScratchSetti
return uniqueSettings
}

func scratchLogin(scratchUser string, features []string, edition string, settings []string, namespace string, release string) {
_, err := ForceScratchCreateLoginAndSaveWithRelease(scratchUser, features, edition, settings, namespace, release, os.Stderr)
func scratchLogin(scratchUser string, features []string, edition string, settings []string, namespace string, release string, duration int) {
_, err := ForceScratchCreateLoginAndSaveWithDuration(scratchUser, features, edition, settings, namespace, release, duration, os.Stderr)
if err != nil {
ErrorAndExit(err.Error())
}
Expand Down
6 changes: 5 additions & 1 deletion lib/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,17 @@ func ForceScratchCreateLoginAndSaveWithNamespace(scratchUser string, features []
}

func ForceScratchCreateLoginAndSaveWithRelease(scratchUser string, features []string, edition string, settings []string, namespace string, release string, output *os.File) (username string, err error) {
return ForceScratchCreateLoginAndSaveWithDuration(scratchUser, features, edition, settings, namespace, release, 7, output)
}

func ForceScratchCreateLoginAndSaveWithDuration(scratchUser string, features []string, edition string, settings []string, namespace string, release string, duration int, output *os.File) (username string, err error) {
force, err := ActiveForce()
if err != nil {
err = errors.New("You must be logged into a Dev Hub org to authenticate as a scratch org user.")
return
}
fmt.Fprintln(os.Stderr, "Creating new Scratch Org...")
scratchOrgId, err := force.CreateScratchOrgWithRelease(scratchUser, features, edition, settings, namespace, release)
scratchOrgId, err := force.CreateScratchOrgWithDuration(scratchUser, features, edition, settings, namespace, release, duration)
if err != nil {
return
}
Expand Down
5 changes: 5 additions & 0 deletions lib/scratch.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,15 @@ func (f *Force) CreateScratchOrgWithUserFeaturesEditionSettingsAndNamespace(user
}

func (f *Force) CreateScratchOrgWithRelease(username string, features []string, edition string, settings []string, namespace string, release string) (id string, err error) {
return f.CreateScratchOrgWithDuration(username, features, edition, settings, namespace, release, 7)
}

func (f *Force) CreateScratchOrgWithDuration(username string, features []string, edition string, settings []string, namespace string, release string, duration int) (id string, err error) {
params := make(map[string]string)
params["ConnectedAppCallbackUrl"] = "http://localhost:1717/OauthRedirect"
params["ConnectedAppConsumerKey"] = "PlatformCLI"
params["Country"] = "US"
params["DurationDays"] = fmt.Sprintf("%d", duration)

if edition != "" {
params["Edition"] = edition
Expand Down
66 changes: 66 additions & 0 deletions lib/scratch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,69 @@ func TestWaitForScratchOrgReady_times_out(t *testing.T) {
t.Errorf("Expected timeout error, got: %v", err)
}
}

func TestCreateScratchOrgWithDuration_sets_DurationDays(t *testing.T) {
var receivedBody map[string]interface{}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" && strings.Contains(r.URL.Path, "ScratchOrgInfo") {
json.NewDecoder(r.Body).Decode(&receivedBody)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]interface{}{
"id": "2SRp0000000MFpOAM",
"success": true,
})
return
}
w.WriteHeader(http.StatusNotFound)
}))
defer server.Close()

force := &Force{
Credentials: &ForceSession{
InstanceUrl: server.URL,
AccessToken: "test-token",
},
}

_, err := force.CreateScratchOrgWithDuration("", []string{}, "", []string{}, "", "", 14)

if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if receivedBody["DurationDays"] != "14" {
t.Errorf("Expected DurationDays to be '14', got: %v", receivedBody["DurationDays"])
}
}

func TestCreateScratchOrgWithRelease_uses_default_duration_of_7(t *testing.T) {
var receivedBody map[string]interface{}
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" && strings.Contains(r.URL.Path, "ScratchOrgInfo") {
json.NewDecoder(r.Body).Decode(&receivedBody)
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(map[string]interface{}{
"id": "2SRp0000000MFpOAM",
"success": true,
})
return
}
w.WriteHeader(http.StatusNotFound)
}))
defer server.Close()

force := &Force{
Credentials: &ForceSession{
InstanceUrl: server.URL,
AccessToken: "test-token",
},
}

_, err := force.CreateScratchOrgWithRelease("", []string{}, "", []string{}, "", "")

if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if receivedBody["DurationDays"] != "7" {
t.Errorf("Expected DurationDays to be '7', got: %v", receivedBody["DurationDays"])
}
}
Loading