mirror of
https://github.com/fleetdm/fleet
synced 2026-04-21 21:47:20 +00:00
New tool to help with github management. Read all about it in the [README](https://github.com/fleetdm/fleet/blob/gkarr-gm/tools/github-manage/README.md) on this branch.
345 lines
8.2 KiB
Go
345 lines
8.2 KiB
Go
package ghapi
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestConvertItemsToIssues(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
items []ProjectItem
|
|
expectedCount int
|
|
}{
|
|
{
|
|
name: "empty items",
|
|
items: []ProjectItem{},
|
|
expectedCount: 0,
|
|
},
|
|
{
|
|
name: "single item with basic fields",
|
|
items: []ProjectItem{
|
|
{
|
|
ID: "item1",
|
|
Content: ProjectItemContent{
|
|
Number: 123,
|
|
Title: "Test Issue",
|
|
Body: "Test description",
|
|
Type: "Issue",
|
|
URL: "https://github.com/org/repo/issues/123",
|
|
},
|
|
Estimate: 5,
|
|
Repository: "org/repo",
|
|
Labels: []string{"bug", "priority-high"},
|
|
Assignees: []string{"user1", "user2"},
|
|
},
|
|
},
|
|
expectedCount: 1,
|
|
},
|
|
{
|
|
name: "item with milestone",
|
|
items: []ProjectItem{
|
|
{
|
|
ID: "item2",
|
|
Content: ProjectItemContent{
|
|
Number: 456,
|
|
Title: "Feature Request",
|
|
Body: "Add new feature",
|
|
Type: "Issue",
|
|
},
|
|
Milestone: &Milestone{
|
|
Number: 1,
|
|
Title: "v1.0",
|
|
Description: "First release",
|
|
DueOn: "2024-12-31T23:59:59Z",
|
|
},
|
|
},
|
|
},
|
|
expectedCount: 1,
|
|
},
|
|
{
|
|
name: "items with different label types",
|
|
items: []ProjectItem{
|
|
{
|
|
ID: "story",
|
|
Content: ProjectItemContent{
|
|
Number: 101,
|
|
Title: "Story Item",
|
|
},
|
|
Labels: []string{"story"},
|
|
},
|
|
{
|
|
ID: "bug",
|
|
Content: ProjectItemContent{
|
|
Number: 102,
|
|
Title: "Bug Item",
|
|
},
|
|
Labels: []string{"bug"},
|
|
},
|
|
{
|
|
ID: "task",
|
|
Content: ProjectItemContent{
|
|
Number: 103,
|
|
Title: "Task Item",
|
|
},
|
|
Labels: []string{"~sub-task"},
|
|
},
|
|
},
|
|
expectedCount: 3,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
issues := ConvertItemsToIssues(tt.items)
|
|
|
|
if len(issues) != tt.expectedCount {
|
|
t.Errorf("Expected %d issues, got %d", tt.expectedCount, len(issues))
|
|
}
|
|
|
|
// Validate specific conversions
|
|
for i, item := range tt.items {
|
|
if i >= len(issues) {
|
|
break
|
|
}
|
|
issue := issues[i]
|
|
|
|
if issue.ID != item.ID {
|
|
t.Errorf("Expected issue ID %s, got %s", item.ID, issue.ID)
|
|
}
|
|
|
|
if issue.Number != item.Content.Number {
|
|
t.Errorf("Expected issue number %d, got %d", item.Content.Number, issue.Number)
|
|
}
|
|
|
|
if issue.Title != item.Content.Title {
|
|
t.Errorf("Expected issue title %s, got %s", item.Content.Title, issue.Title)
|
|
}
|
|
|
|
if issue.Body != item.Content.Body {
|
|
t.Errorf("Expected issue body %s, got %s", item.Content.Body, issue.Body)
|
|
}
|
|
|
|
if issue.Estimate != item.Estimate {
|
|
t.Errorf("Expected issue estimate %d, got %d", item.Estimate, issue.Estimate)
|
|
}
|
|
|
|
// Check milestone conversion
|
|
if item.Milestone != nil {
|
|
if issue.Milestone == nil {
|
|
t.Error("Expected milestone to be converted, got nil")
|
|
} else {
|
|
if issue.Milestone.Number != item.Milestone.Number {
|
|
t.Errorf("Expected milestone number %d, got %d", item.Milestone.Number, issue.Milestone.Number)
|
|
}
|
|
if issue.Milestone.Title != item.Milestone.Title {
|
|
t.Errorf("Expected milestone title %s, got %s", item.Milestone.Title, issue.Milestone.Title)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check assignees conversion
|
|
if len(item.Assignees) != len(issue.Assignees) {
|
|
t.Errorf("Expected %d assignees, got %d", len(item.Assignees), len(issue.Assignees))
|
|
}
|
|
|
|
// Check label conversion and typename assignment
|
|
for _, label := range item.Labels {
|
|
found := false
|
|
for _, issueLabel := range issue.Labels {
|
|
if issueLabel.Name == label {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Errorf("Expected label %s to be converted", label)
|
|
}
|
|
|
|
// Check typename assignment
|
|
switch label {
|
|
case "story":
|
|
if issue.Typename != "Feature" {
|
|
t.Errorf("Expected typename 'Feature' for story label, got %s", issue.Typename)
|
|
}
|
|
case "bug":
|
|
if issue.Typename != "Bug" {
|
|
t.Errorf("Expected typename 'Bug' for bug label, got %s", issue.Typename)
|
|
}
|
|
case "~sub-task":
|
|
if issue.Typename != "Task" {
|
|
t.Errorf("Expected typename 'Task' for ~sub-task label, got %s", issue.Typename)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestStructMarshaling(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
data interface{}
|
|
}{
|
|
{
|
|
name: "Author struct",
|
|
data: Author{
|
|
Login: "testuser",
|
|
IsBot: false,
|
|
Name: "Test User",
|
|
ID: "123",
|
|
},
|
|
},
|
|
{
|
|
name: "Label struct",
|
|
data: Label{
|
|
ID: "label1",
|
|
Name: "bug",
|
|
Description: "Something isn't working",
|
|
Color: "ff0000",
|
|
},
|
|
},
|
|
{
|
|
name: "Milestone struct",
|
|
data: Milestone{
|
|
Number: 1,
|
|
Title: "v1.0",
|
|
Description: "First release",
|
|
DueOn: "2024-12-31T23:59:59Z",
|
|
},
|
|
},
|
|
{
|
|
name: "Issue struct",
|
|
data: Issue{
|
|
Typename: "Bug",
|
|
ID: "issue1",
|
|
Number: 123,
|
|
Title: "Test Issue",
|
|
Body: "Test description",
|
|
Author: Author{Login: "testuser"},
|
|
Assignees: []Author{{Login: "assignee1"}},
|
|
CreatedAt: "2024-01-01T00:00:00Z",
|
|
UpdatedAt: "2024-01-01T00:00:00Z",
|
|
State: "open",
|
|
Labels: []Label{{Name: "bug"}},
|
|
Milestone: &Milestone{Title: "v1.0"},
|
|
Estimate: 5,
|
|
},
|
|
},
|
|
{
|
|
name: "ProjectItem struct",
|
|
data: ProjectItem{
|
|
ID: "item1",
|
|
Title: "Test Item",
|
|
Content: ProjectItemContent{
|
|
Body: "Test body",
|
|
Number: 123,
|
|
Title: "Test Title",
|
|
Type: "Issue",
|
|
URL: "https://example.com",
|
|
},
|
|
Estimate: 3,
|
|
Repository: "org/repo",
|
|
Labels: []string{"bug", "feature"},
|
|
Assignees: []string{"user1"},
|
|
Status: "In Progress",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Test marshaling
|
|
jsonData, err := json.Marshal(tt.data)
|
|
if err != nil {
|
|
t.Errorf("Failed to marshal %s: %v", tt.name, err)
|
|
return
|
|
}
|
|
|
|
// Test unmarshaling
|
|
dataType := reflect.TypeOf(tt.data)
|
|
newValue := reflect.New(dataType).Interface()
|
|
|
|
err = json.Unmarshal(jsonData, newValue)
|
|
if err != nil {
|
|
t.Errorf("Failed to unmarshal %s: %v", tt.name, err)
|
|
return
|
|
}
|
|
|
|
// Compare original and unmarshaled data
|
|
originalValue := reflect.ValueOf(tt.data)
|
|
unmarshaledValue := reflect.ValueOf(newValue).Elem()
|
|
|
|
if !reflect.DeepEqual(originalValue.Interface(), unmarshaledValue.Interface()) {
|
|
t.Errorf("Original and unmarshaled %s data do not match", tt.name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestProjectItemsResponse(t *testing.T) {
|
|
response := ProjectItemsResponse{
|
|
Items: []ProjectItem{
|
|
{ID: "item1", Title: "Item 1"},
|
|
{ID: "item2", Title: "Item 2"},
|
|
},
|
|
TotalCount: 2,
|
|
}
|
|
|
|
jsonData, err := json.Marshal(response)
|
|
if err != nil {
|
|
t.Errorf("Failed to marshal ProjectItemsResponse: %v", err)
|
|
}
|
|
|
|
var unmarshaled ProjectItemsResponse
|
|
err = json.Unmarshal(jsonData, &unmarshaled)
|
|
if err != nil {
|
|
t.Errorf("Failed to unmarshal ProjectItemsResponse: %v", err)
|
|
}
|
|
|
|
if unmarshaled.TotalCount != response.TotalCount {
|
|
t.Errorf("Expected TotalCount %d, got %d", response.TotalCount, unmarshaled.TotalCount)
|
|
}
|
|
|
|
if len(unmarshaled.Items) != len(response.Items) {
|
|
t.Errorf("Expected %d items, got %d", len(response.Items), len(unmarshaled.Items))
|
|
}
|
|
}
|
|
|
|
func TestProjectFieldsResponse(t *testing.T) {
|
|
response := ProjectFieldsResponse{
|
|
Fields: []ProjectField{
|
|
{
|
|
ID: "field1",
|
|
Name: "Status",
|
|
Type: "select",
|
|
Options: []ProjectFieldOption{
|
|
{ID: "opt1", Name: "In Progress"},
|
|
{ID: "opt2", Name: "Done"},
|
|
},
|
|
},
|
|
},
|
|
TotalCount: 1,
|
|
}
|
|
|
|
jsonData, err := json.Marshal(response)
|
|
if err != nil {
|
|
t.Errorf("Failed to marshal ProjectFieldsResponse: %v", err)
|
|
}
|
|
|
|
var unmarshaled ProjectFieldsResponse
|
|
err = json.Unmarshal(jsonData, &unmarshaled)
|
|
if err != nil {
|
|
t.Errorf("Failed to unmarshal ProjectFieldsResponse: %v", err)
|
|
}
|
|
|
|
if unmarshaled.TotalCount != response.TotalCount {
|
|
t.Errorf("Expected TotalCount %d, got %d", response.TotalCount, unmarshaled.TotalCount)
|
|
}
|
|
|
|
if len(unmarshaled.Fields) != len(response.Fields) {
|
|
t.Errorf("Expected %d fields, got %d", len(response.Fields), len(unmarshaled.Fields))
|
|
}
|
|
}
|