Skip to content

Commit 5909a31

Browse files
authored
Merge pull request #22 from doneill/task/jdo-41-patrols-status
Add patrols status flag
2 parents 1845bbd + 5521558 commit 5909a31

3 files changed

Lines changed: 123 additions & 33 deletions

File tree

api/apipatrols.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,13 @@ type DateRangeFilter struct {
6363
// Client methods
6464
// ----------------------------------------------
6565

66-
func (c *Client) Patrols(days int) (*PatrolsResponse, error) {
67-
var endpoint string
66+
func (c *Client) Patrols(days int, status string) (*PatrolsResponse, error) {
67+
params := url.Values{}
68+
params.Add("exclude_empty_patrols", "true")
69+
70+
if status != "" {
71+
params.Add("status", status)
72+
}
6873

6974
if days > 0 {
7075
now := time.Now().UTC()
@@ -82,15 +87,11 @@ func (c *Client) Patrols(days int) (*PatrolsResponse, error) {
8287
return nil, fmt.Errorf("failed to marshal date filter: %w", err)
8388
}
8489

85-
params := url.Values{}
8690
params.Add("filter", string(filterJSON))
87-
params.Add("exclude_empty_patrols", "true")
88-
89-
endpoint = fmt.Sprintf("%s?%s", API_PATROLS, params.Encode())
90-
} else {
91-
endpoint = fmt.Sprintf("%s?exclude_empty_patrols=true", API_PATROLS)
9291
}
9392

93+
endpoint := fmt.Sprintf("%s?%s", API_PATROLS, params.Encode())
94+
9495
req, err := c.newRequest("GET", endpoint, false)
9596
if err != nil {
9697
return nil, fmt.Errorf("failed to create patrols request: %w", err)

api/patrols_test.go

Lines changed: 93 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,18 @@ import (
1111

1212
func TestPatrols(t *testing.T) {
1313
tests := []struct {
14-
name string
15-
days int
16-
mockResponse string
17-
expectedError bool
18-
validateResult func(*testing.T, *PatrolsResponse)
14+
name string
15+
days int
16+
status string
17+
mockResponse string
18+
expectedError bool
19+
validateResult func(*testing.T, *PatrolsResponse)
20+
validateRequest func(*testing.T, *http.Request)
1921
}{
2022
{
21-
name: "successful response without date filter",
22-
days: 0,
23+
name: "successful response without filters",
24+
days: 0,
25+
status: "",
2326
mockResponse: `{
2427
"data": {
2528
"count": 1,
@@ -51,6 +54,17 @@ func TestPatrols(t *testing.T) {
5154
}
5255
}`,
5356
expectedError: false,
57+
validateRequest: func(t *testing.T, r *http.Request) {
58+
if !strings.Contains(r.URL.String(), "exclude_empty_patrols=true") {
59+
t.Error("Expected exclude_empty_patrols parameter")
60+
}
61+
if strings.Contains(r.URL.String(), "status=") {
62+
t.Error("Unexpected status parameter")
63+
}
64+
if strings.Contains(r.URL.String(), "filter=") {
65+
t.Error("Unexpected filter parameter")
66+
}
67+
},
5468
validateResult: func(t *testing.T, response *PatrolsResponse) {
5569
if response == nil {
5670
t.Fatal("Expected non-nil response")
@@ -77,8 +91,9 @@ func TestPatrols(t *testing.T) {
7791
},
7892
},
7993
{
80-
name: "successful response with date filter",
81-
days: 7,
94+
name: "successful response with date filter",
95+
days: 7,
96+
status: "",
8297
mockResponse: `{
8398
"data": {
8499
"count": 1,
@@ -96,6 +111,17 @@ func TestPatrols(t *testing.T) {
96111
}
97112
}`,
98113
expectedError: false,
114+
validateRequest: func(t *testing.T, r *http.Request) {
115+
if !strings.Contains(r.URL.String(), "exclude_empty_patrols=true") {
116+
t.Error("Expected exclude_empty_patrols parameter")
117+
}
118+
if !strings.Contains(r.URL.String(), "filter=") {
119+
t.Error("Expected filter parameter")
120+
}
121+
if !strings.Contains(r.URL.String(), "patrols_overlap_daterange") {
122+
t.Error("Expected patrols_overlap_daterange in filter")
123+
}
124+
},
99125
validateResult: func(t *testing.T, response *PatrolsResponse) {
100126
if response == nil {
101127
t.Fatal("Expected non-nil response")
@@ -106,10 +132,60 @@ func TestPatrols(t *testing.T) {
106132
},
107133
},
108134
{
109-
name: "error response",
110-
days: 0,
111-
mockResponse: `{"status": {"code": 500, "message": "Internal Server Error"}}`,
112-
expectedError: true,
135+
name: "successful response with status filter",
136+
days: 7,
137+
status: "active",
138+
mockResponse: `{
139+
"data": {
140+
"count": 1,
141+
"results": [
142+
{
143+
"id": "test789",
144+
"serial_number": 1003,
145+
"state": "active"
146+
}
147+
]
148+
},
149+
"status": {
150+
"code": 200,
151+
"message": "OK"
152+
}
153+
}`,
154+
expectedError: false,
155+
validateRequest: func(t *testing.T, r *http.Request) {
156+
if !strings.Contains(r.URL.String(), "exclude_empty_patrols=true") {
157+
t.Error("Expected exclude_empty_patrols parameter")
158+
}
159+
if !strings.Contains(r.URL.String(), "status=active") {
160+
t.Error("Expected status parameter")
161+
}
162+
if !strings.Contains(r.URL.String(), "filter=") {
163+
t.Error("Expected filter parameter")
164+
}
165+
},
166+
validateResult: func(t *testing.T, response *PatrolsResponse) {
167+
if response == nil {
168+
t.Fatal("Expected non-nil response")
169+
}
170+
if len(response.Data.Results) != 1 {
171+
t.Errorf("Expected 1 result, got %d", len(response.Data.Results))
172+
}
173+
if response.Data.Results[0].State != "active" {
174+
t.Errorf("Expected state 'active', got '%s'", response.Data.Results[0].State)
175+
}
176+
},
177+
},
178+
{
179+
name: "error response",
180+
days: 0,
181+
status: "",
182+
mockResponse: `{"status": {"code": 500, "message": "Internal Server Error"}}`,
183+
expectedError: true,
184+
validateRequest: func(t *testing.T, r *http.Request) {
185+
if !strings.Contains(r.URL.String(), "exclude_empty_patrols=true") {
186+
t.Error("Expected exclude_empty_patrols parameter")
187+
}
188+
},
113189
validateResult: nil,
114190
},
115191
}
@@ -122,13 +198,8 @@ func TestPatrols(t *testing.T) {
122198
t.Errorf("Expected GET request, got %s", r.Method)
123199
}
124200

125-
if tt.days > 0 {
126-
if !strings.Contains(r.URL.String(), "filter=") {
127-
t.Error("Expected filter parameter in URL for date-filtered request")
128-
}
129-
if !strings.Contains(r.URL.String(), "patrols_overlap_daterange") {
130-
t.Error("Expected patrols_overlap_daterange in filter")
131-
}
201+
if tt.validateRequest != nil {
202+
tt.validateRequest(t, r)
132203
}
133204

134205
// Return mock response
@@ -143,7 +214,7 @@ func TestPatrols(t *testing.T) {
143214
defer server.Close()
144215

145216
client := ERClient("test", "test-token", server.URL)
146-
response, err := client.Patrols(tt.days)
217+
response, err := client.Patrols(tt.days, tt.status)
147218

148219
if tt.expectedError {
149220
if err == nil {
@@ -203,7 +274,7 @@ func TestDateRangeFilter(t *testing.T) {
203274
defer server.Close()
204275

205276
client := ERClient("test", "test-token", server.URL)
206-
_, err := client.Patrols(7)
277+
_, err := client.Patrols(7, "")
207278
if err != nil {
208279
t.Errorf("Unexpected error: %v", err)
209280
}

cmd/patrols.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,16 @@ import (
1212
"github.com/spf13/cobra"
1313
)
1414

15-
var days int
15+
var (
16+
days int
17+
status string
18+
)
19+
20+
var validStatuses = map[string]bool{
21+
"active": true,
22+
"done": true,
23+
"cancelled": true,
24+
}
1625

1726
// ----------------------------------------------
1827
// patrols command
@@ -22,6 +31,14 @@ var patrolsCmd = &cobra.Command{
2231
Use: "patrols",
2332
Short: "Get patrols data",
2433
Long: `Return patrol data including serial number, state, ID, location, and time information`,
34+
PreRunE: func(cmd *cobra.Command, args []string) error {
35+
if status != "" {
36+
if !validStatuses[status] {
37+
return fmt.Errorf("invalid status value: %s\nValid status values are: active, done, cancelled", status)
38+
}
39+
}
40+
return nil
41+
},
2542
Run: func(cmd *cobra.Command, args []string) {
2643
patrols()
2744
},
@@ -37,7 +54,7 @@ func patrols() {
3754
}
3855

3956
func handlePatrols(client *api.Client) {
40-
patrolsResponse, err := client.Patrols(days)
57+
patrolsResponse, err := client.Patrols(days, status)
4158
if err != nil {
4259
log.Fatalf("Error getting patrols: %v", err)
4360
}
@@ -138,5 +155,6 @@ func configurePatrolsTable() *tablewriter.Table {
138155

139156
func init() {
140157
rootCmd.AddCommand(patrolsCmd)
141-
patrolsCmd.Flags().IntVarP(&days, "days", "d", 0, "Number of days to fetch patrols for (defaults to all)")
158+
patrolsCmd.Flags().IntVarP(&days, "days", "d", 7, "Number of days to fetch patrols for")
159+
patrolsCmd.Flags().StringVarP(&status, "status", "s", "", "Patrol status (active, done, or cancelled)")
142160
}

0 commit comments

Comments
 (0)