Skip to content

Commit

Permalink
Refactor tuple import output to include total count and improve respo…
Browse files Browse the repository at this point in the history
…nse structure
  • Loading branch information
Siddhant-K-code committed Jan 8, 2025
1 parent 3923fed commit 9a6bd9c
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 100 deletions.
28 changes: 9 additions & 19 deletions cmd/tuple/write.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,29 +154,19 @@ func writeTuplesFromFile(flags *flag.FlagSet, fgaClient *client.OpenFgaClient) e
return err
}

stats.SuccessfulTuples = len(response.Successful)
stats.FailedTuples = len(response.Failed)
outputResponse := make(map[string]interface{})

if !hideImportedTuples {
err = output.Display(response)
if err != nil {
return err
}
} else if len(response.Failed) > 0 {
err = output.Display(map[string]interface{}{
"failed": response.Failed,
})
if err != nil {
return err
}
if !hideImportedTuples && len(response.Successful) > 0 {
outputResponse["successful"] = response.Successful
}

if len(response.Failed) > 0 {
outputResponse["failed"] = response.Failed
}

fmt.Printf("\nImport Summary:\n")
fmt.Printf("Total tuples processed: %d\n", stats.TotalTuples)
fmt.Printf("Successfully imported: %d\n", stats.SuccessfulTuples)
fmt.Printf("Failed: %d\n", stats.FailedTuples)
outputResponse["total_count"] = stats.TotalTuples

return nil
return output.Display(outputResponse)

Check failure on line 169 in cmd/tuple/write.go

View workflow job for this annotation

GitHub Actions / Lints

error returned from external package is unwrapped: sig: func github.com/openfga/cli/internal/output.Display(data any) error (wrapcheck)
}

func init() {
Expand Down
136 changes: 55 additions & 81 deletions cmd/tuple/write_test.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
package tuple

import (
"bytes"
"fmt"
"io"
"os"
"strings"
"encoding/json"
"testing"

openfga "github.com/openfga/go-sdk"
"github.com/openfga/go-sdk/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/openfga/cli/internal/output"
"github.com/openfga/cli/internal/tuplefile"
)

Expand Down Expand Up @@ -242,7 +237,7 @@ func TestWriteTuplesWithImportStats(t *testing.T) {
expectedError string
}{
{
name: "shows all tuples when hide-imported-tuples is false",
name: "shows successful tuples and total count when hide-imported-tuples is false",
file: "testdata/tuples.json",
hideImportedTuples: false,
expectedStats: ImportStats{
Expand All @@ -251,24 +246,25 @@ func TestWriteTuplesWithImportStats(t *testing.T) {
FailedTuples: 0,
},
expectedOutput: `{
"successful": [
{
"user": "user:anne",
"relation": "owner",
"object": "folder:product"
},
{
"user": "folder:product",
"relation": "parent",
"object": "folder:product-2021"
},
{
"user": "user:beth",
"relation": "viewer",
"object": "folder:product-2021"
}
]
}`,
"successful": [
{
"user": "user:anne",
"relation": "owner",
"object": "folder:product"
},
{
"user": "folder:product",
"relation": "parent",
"object": "folder:product-2021"
},
{
"user": "user:beth",
"relation": "viewer",
"object": "folder:product-2021"
}
],
"total_count": 3
}`,
},
{
name: "hides successful tuples when hide-imported-tuples is true",
Expand All @@ -279,10 +275,12 @@ func TestWriteTuplesWithImportStats(t *testing.T) {
SuccessfulTuples: 3,
FailedTuples: 0,
},
expectedOutput: "",
expectedOutput: `{
"total_count": 3
}`,
},
{
name: "always shows failed tuples even when hide-imported-tuples is true",
name: "shows failed tuples and total count when there are failures",
file: "testdata/tuples_with_errors.json",
hideImportedTuples: true,
expectedStats: ImportStats{
Expand All @@ -291,61 +289,50 @@ func TestWriteTuplesWithImportStats(t *testing.T) {
FailedTuples: 2,
},
expectedOutput: `{
"failed": [
{
"user": "invalid:user",
"relation": "invalid",
"object": "invalid:object"
},
{
"user": "another:invalid",
"relation": "invalid",
"object": "invalid:object"
}
]
}`,
"failed": [
{
"user": "invalid:user",
"relation": "invalid",
"object": "invalid:object"
},
{
"user": "another:invalid",
"relation": "invalid",
"object": "invalid:object"
}
],
"total_count": 3
}`,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()

old := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w

hideImportedTuples = test.hideImportedTuples

tuples, err := tuplefile.ReadTupleFile(test.file)
if err == nil {
response := map[string][]client.ClientTupleKey{}
response := make(map[string]interface{})

if !hideImportedTuples || test.expectedStats.FailedTuples > 0 {
if test.expectedStats.SuccessfulTuples > 0 {
response["successful"] = tuples[:test.expectedStats.SuccessfulTuples]
}
if test.expectedStats.FailedTuples > 0 {
response["failed"] = tuples[test.expectedStats.SuccessfulTuples:]
}
err = output.Display(response)
if err != nil {
t.Fatal(err)
}
if !test.hideImportedTuples && test.expectedStats.SuccessfulTuples > 0 {
response["successful"] = tuples[:test.expectedStats.SuccessfulTuples]
}
}

fmt.Fprintf(w, "\nImport Summary:\n")
fmt.Fprintf(w, "Total tuples processed: %d\n", test.expectedStats.TotalTuples)
fmt.Fprintf(w, "Successfully imported: %d\n", test.expectedStats.SuccessfulTuples)
fmt.Fprintf(w, "Failed: %d\n", test.expectedStats.FailedTuples)
if test.expectedStats.FailedTuples > 0 {
response["failed"] = tuples[test.expectedStats.SuccessfulTuples:]
}

w.Close()
os.Stdout = old
response["total_count"] = len(tuples)

var buf bytes.Buffer
io.Copy(&buf, r)
output := buf.String()
output, err := json.Marshal(response)
if err != nil {
t.Fatal(err)
}

if test.expectedOutput != "" {
assert.JSONEq(t, test.expectedOutput, string(output))
}
}

if test.expectedError != "" {
require.EqualError(t, err, test.expectedError)
Expand All @@ -354,19 +341,6 @@ func TestWriteTuplesWithImportStats(t *testing.T) {

require.NoError(t, err)
assert.Equal(t, test.expectedStats.TotalTuples, len(tuples))

Check failure on line 343 in cmd/tuple/write_test.go

View workflow job for this annotation

GitHub Actions / Lints

len: use assert.Len (testifylint)
assert.Contains(t, output, fmt.Sprintf("Total tuples processed: %d", test.expectedStats.TotalTuples))
assert.Contains(t, output, fmt.Sprintf("Successfully imported: %d", test.expectedStats.SuccessfulTuples))
assert.Contains(t, output, fmt.Sprintf("Failed: %d", test.expectedStats.FailedTuples))

if test.expectedOutput != "" {
jsonPart := output
if idx := strings.Index(output, "\nImport Summary"); idx >= 0 {
jsonPart = output[:idx]
}
if jsonPart != "" {
assert.JSONEq(t, test.expectedOutput, jsonPart)
}
}
})
}
}

0 comments on commit 9a6bd9c

Please sign in to comment.