• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

UiPath / uipathcli / 22833181054

09 Mar 2026 12:15AM UTC coverage: 90.831% (-0.08%) from 90.914%
22833181054

Pull #212

github

Chibi Vikram
Add direct Execute tests for defensive parameter validation

Test parameter type assertion failure and empty value checks by calling
Execute directly, bypassing CLI framework validation. Covers
getStringParameter false branch and source/solutionId empty checks in
unpack, push, pull, and publish commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pull Request #212: Add studio solution commands, skill, and agents.md

606 of 674 new or added lines in 16 files covered. (89.91%)

3 existing lines in 1 file now uncovered.

7380 of 8125 relevant lines covered (90.83%)

1.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.94
/plugin/studio/solution/pull/solution_pull_command.go
1
// Package pull implements the command plugin for pulling a solution
2
// from UiPath Studio Web as a .uis file.
3
package pull
4

5
import (
6
        "bytes"
7
        "encoding/json"
8
        "errors"
9
        "fmt"
10
        "io"
11
        "net/http"
12
        "os"
13
        "path/filepath"
14

15
        "github.com/UiPath/uipathcli/log"
16
        "github.com/UiPath/uipathcli/output"
17
        "github.com/UiPath/uipathcli/plugin"
18
        "github.com/UiPath/uipathcli/utils/api"
19
)
20

21
// The SolutionPullCommand pulls a solution from Studio Web.
22
type SolutionPullCommand struct{}
23

24
func (c SolutionPullCommand) Command() plugin.Command {
1✔
25
        return *plugin.NewCommand("studio").
1✔
26
                WithCategory("solution", "UiPath Solution management", "Pack, unpack, push and pull UiPath Maestro solutions.").
1✔
27
                WithOperation("pull", "Pull Solution", "Pulls a solution from UiPath Studio Web as a .uis file").
1✔
28
                WithParameter(plugin.NewParameter("solution-id", plugin.ParameterTypeString, "Solution ID to pull").
1✔
29
                        WithRequired(true)).
1✔
30
                WithParameter(plugin.NewParameter("destination", plugin.ParameterTypeString, "Output .uis file path").
1✔
31
                        WithDefaultValue(""))
1✔
32
}
1✔
33

34
func (c SolutionPullCommand) Execute(ctx plugin.ExecutionContext, writer output.OutputWriter, logger log.Logger) error {
1✔
35
        if ctx.Organization == "" {
2✔
36
                return errors.New("Organization is not set")
1✔
37
        }
1✔
38
        solutionId := c.getStringParameter("solution-id", "", ctx.Parameters)
1✔
39
        if solutionId == "" {
2✔
40
                return errors.New("Solution ID is required")
1✔
41
        }
1✔
42
        destination := c.getStringParameter("destination", "", ctx.Parameters)
1✔
43
        if destination == "" {
2✔
44
                destination = solutionId + ".uis"
1✔
45
        }
1✔
46
        destination, _ = filepath.Abs(destination)
1✔
47

1✔
48
        params := newSolutionPullParams(solutionId, destination, ctx.BaseUri, ctx.Organization, ctx.Auth, ctx.Debug, ctx.Settings)
1✔
49
        result, err := c.pull(*params, logger)
1✔
50
        if err != nil {
2✔
51
                return err
1✔
52
        }
1✔
53

54
        jsonData, err := json.Marshal(result)
1✔
55
        if err != nil {
1✔
NEW
56
                return fmt.Errorf("Pull command failed: %w", err)
×
NEW
57
        }
×
58
        return writer.WriteResponse(*output.NewResponseInfo(http.StatusOK, "200 OK", "HTTP/1.1", map[string][]string{}, bytes.NewReader(jsonData)))
1✔
59
}
60

61
func (c SolutionPullCommand) pull(params solutionPullParams, logger log.Logger) (*solutionPullResult, error) {
1✔
62
        client := api.NewStudioClient(params.BaseUri, params.Organization, params.Auth.Token, params.Debug, params.Settings, logger)
1✔
63
        body, err := client.PullSolution(params.SolutionId)
1✔
64
        if err != nil {
2✔
65
                return nil, err
1✔
66
        }
1✔
67
        defer func() { _ = body.Close() }()
2✔
68

69
        outFile, err := os.Create(params.Destination)
1✔
70
        if err != nil {
2✔
71
                return nil, fmt.Errorf("Cannot create output file: %w", err)
1✔
72
        }
1✔
73
        defer func() { _ = outFile.Close() }()
2✔
74

75
        written, err := io.Copy(outFile, body)
1✔
76
        if err != nil {
1✔
NEW
77
                _ = os.Remove(params.Destination)
×
NEW
78
                return nil, fmt.Errorf("Error writing solution file: %w", err)
×
NEW
79
        }
×
80

81
        return newSucceededSolutionPullResult(params.Destination, params.SolutionId, written), nil
1✔
82
}
83

84
func (c SolutionPullCommand) getStringParameter(name string, defaultValue string, parameters []plugin.ExecutionParameter) string {
1✔
85
        result := defaultValue
1✔
86
        for _, p := range parameters {
2✔
87
                if p.Name == name {
2✔
88
                        if data, ok := p.Value.(string); ok {
2✔
89
                                result = data
1✔
90
                                break
1✔
91
                        }
92
                }
93
        }
94
        return result
1✔
95
}
96

97
func NewSolutionPullCommand() *SolutionPullCommand {
1✔
98
        return &SolutionPullCommand{}
1✔
99
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc