Skip to content

Commit 3686c2a

Browse files
committed
feat
(jira) Add BoardConfiguration unmarshal tests * Verify SubQuery parsing for kanban boards with, without, and empty sub-filter objects * Include a test using a full Jira Cloud response payload to validate all fields
1 parent d1ecded commit 3686c2a

1 file changed

Lines changed: 137 additions & 0 deletions

File tree

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
package tasks
19+
20+
import (
21+
"encoding/json"
22+
"testing"
23+
)
24+
25+
func Test_BoardConfiguration_UnmarshalSubQuery(t *testing.T) {
26+
tests := []struct {
27+
name string
28+
raw string
29+
wantSubQuery string
30+
wantFilterID string
31+
wantID int
32+
wantName string
33+
wantType string
34+
wantColumnCount int
35+
wantRankFieldID int
36+
}{
37+
{
38+
name: "kanban board with sub-filter object",
39+
raw: `{"id":1201,"name":"Squad 5","type":"kanban",` +
40+
`"self":"https://example.atlassian.net/rest/agile/1.0/board/1201/configuration",` +
41+
`"filter":{"id":"17696","self":"https://example.atlassian.net/rest/api/2/filter/17696"},` +
42+
`"subQuery":{"query":"fixVersion in unreleasedVersions() OR fixVersion is EMPTY"},` +
43+
`"columnConfig":{"columns":[{"name":"Backlog","statuses":[{"id":"1","self":"https://example.atlassian.net/rest/api/2/status/1"}]},` +
44+
`{"name":"Done","statuses":[{"id":"10037","self":"https://example.atlassian.net/rest/api/2/status/10037"}]}],` +
45+
`"constraintType":"issueCount"},"ranking":{"rankCustomFieldId":10019}}`,
46+
wantSubQuery: "fixVersion in unreleasedVersions() OR fixVersion is EMPTY",
47+
wantFilterID: "17696",
48+
wantID: 1201,
49+
wantName: "Squad 5",
50+
wantType: "kanban",
51+
wantColumnCount: 2,
52+
wantRankFieldID: 10019,
53+
},
54+
{
55+
name: "board without subQuery field",
56+
raw: `{"id":500,"name":"No SubFilter Board","type":"scrum",` +
57+
`"self":"https://example.atlassian.net/rest/agile/1.0/board/500/configuration",` +
58+
`"filter":{"id":"99999","self":"https://example.atlassian.net/rest/api/2/filter/99999"},` +
59+
`"columnConfig":{"columns":[],"constraintType":"issueCount"},"ranking":{"rankCustomFieldId":10019}}`,
60+
wantSubQuery: "",
61+
wantFilterID: "99999",
62+
wantID: 500,
63+
wantName: "No SubFilter Board",
64+
wantType: "scrum",
65+
wantColumnCount: 0,
66+
wantRankFieldID: 10019,
67+
},
68+
{
69+
name: "board with empty subQuery object",
70+
raw: `{"id":600,"name":"Empty SubQuery Board","type":"kanban",` +
71+
`"self":"https://example.atlassian.net/rest/agile/1.0/board/600/configuration",` +
72+
`"filter":{"id":"11111","self":"https://example.atlassian.net/rest/api/2/filter/11111"},` +
73+
`"subQuery":{},` +
74+
`"columnConfig":{"columns":[],"constraintType":"issueCount"},"ranking":{"rankCustomFieldId":10019}}`,
75+
wantSubQuery: "",
76+
wantFilterID: "11111",
77+
wantID: 600,
78+
wantName: "Empty SubQuery Board",
79+
wantType: "kanban",
80+
wantColumnCount: 0,
81+
wantRankFieldID: 10019,
82+
},
83+
}
84+
85+
for _, tt := range tests {
86+
t.Run(tt.name, func(t *testing.T) {
87+
var bc BoardConfiguration
88+
if err := json.Unmarshal([]byte(tt.raw), &bc); err != nil {
89+
t.Fatalf("failed to unmarshal BoardConfiguration: %v", err)
90+
}
91+
if bc.SubQuery.Query != tt.wantSubQuery {
92+
t.Errorf("SubQuery.Query = %q, want %q", bc.SubQuery.Query, tt.wantSubQuery)
93+
}
94+
if bc.Filter.ID != tt.wantFilterID {
95+
t.Errorf("Filter.ID = %q, want %q", bc.Filter.ID, tt.wantFilterID)
96+
}
97+
if bc.ID != tt.wantID {
98+
t.Errorf("ID = %d, want %d", bc.ID, tt.wantID)
99+
}
100+
if bc.Name != tt.wantName {
101+
t.Errorf("Name = %q, want %q", bc.Name, tt.wantName)
102+
}
103+
if bc.Type != tt.wantType {
104+
t.Errorf("Type = %q, want %q", bc.Type, tt.wantType)
105+
}
106+
if len(bc.ColumnConfig.Columns) != tt.wantColumnCount {
107+
t.Errorf("ColumnConfig.Columns length = %d, want %d", len(bc.ColumnConfig.Columns), tt.wantColumnCount)
108+
}
109+
if bc.Ranking.RankCustomFieldID != tt.wantRankFieldID {
110+
t.Errorf("Ranking.RankCustomFieldID = %d, want %d", bc.Ranking.RankCustomFieldID, tt.wantRankFieldID)
111+
}
112+
})
113+
}
114+
}
115+
116+
func Test_BoardConfiguration_FullJiraCloudResponse(t *testing.T) {
117+
// Exact response payload from Jira Cloud for Board 1201 (Squad 5)
118+
raw := `{"id":1201,"name":"Squad 5","type":"kanban","self":"https://rakutenadvertising.atlassian.net/rest/agile/1.0/board/1201/configuration","location":{"type":"user","id":"62d8159bb2e6b1992b5be875","self":"https://rakutenadvertising.atlassian.net/rest/api/2/user?accountId=62d8159bb2e6b1992b5be875"},"filter":{"id":"17696","self":"https://rakutenadvertising.atlassian.net/rest/api/2/filter/17696"},"subQuery":{"query":"fixVersion in unreleasedVersions() OR fixVersion is EMPTY"},"columnConfig":{"columns":[{"name":"Backlog","statuses":[{"id":"1","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/1"},{"id":"4","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/4"},{"id":"10016","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10016"},{"id":"10003","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10003"}]},{"name":"To Do","statuses":[{"id":"10054","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10054"}]},{"name":"Blocked","statuses":[{"id":"10019","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10019"}]},{"name":"In Development","statuses":[{"id":"10017","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10017"},{"id":"10177","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10177"},{"id":"10038","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10038"}]},{"name":"Code Review","statuses":[{"id":"10024","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10024"}]},{"name":"Ready for QA","statuses":[{"id":"10029","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10029"},{"id":"10033","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10033"}]},{"name":"In QA","statuses":[{"id":"10018","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10018"},{"id":"10158","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10158"}]},{"name":"Done","statuses":[{"id":"10037","self":"https://rakutenadvertising.atlassian.net/rest/api/2/status/10037"}]}],"constraintType":"issueCount"},"ranking":{"rankCustomFieldId":10019}}`
119+
120+
var bc BoardConfiguration
121+
if err := json.Unmarshal([]byte(raw), &bc); err != nil {
122+
t.Fatalf("failed to unmarshal real Jira Cloud response: %v", err)
123+
}
124+
125+
if bc.SubQuery.Query != "fixVersion in unreleasedVersions() OR fixVersion is EMPTY" {
126+
t.Errorf("SubQuery.Query = %q, want the fixVersion sub-filter", bc.SubQuery.Query)
127+
}
128+
if bc.Filter.ID != "17696" {
129+
t.Errorf("Filter.ID = %q, want %q", bc.Filter.ID, "17696")
130+
}
131+
if len(bc.ColumnConfig.Columns) != 8 {
132+
t.Errorf("ColumnConfig.Columns length = %d, want 8", len(bc.ColumnConfig.Columns))
133+
}
134+
if bc.Location.ID != "62d8159bb2e6b1992b5be875" {
135+
t.Errorf("Location.ID = %q, want %q", bc.Location.ID, "62d8159bb2e6b1992b5be875")
136+
}
137+
}

0 commit comments

Comments
 (0)