github.com/openfga/openfga@v1.5.4-rc1/tests/writemodel/writemodel.go (about)

     1  // Package writemodel contains integration tests for the WriteAuthorizationModel API.
     2  package writemodel
     3  
     4  import (
     5  	"context"
     6  	"testing"
     7  
     8  	openfgav1 "github.com/openfga/api/proto/openfga/v1"
     9  	parser "github.com/openfga/language/pkg/go/transformer"
    10  	"github.com/stretchr/testify/require"
    11  	"google.golang.org/grpc"
    12  	"google.golang.org/grpc/status"
    13  
    14  	"github.com/openfga/openfga/pkg/typesystem"
    15  )
    16  
    17  var testCases = map[string]struct {
    18  	model string
    19  	code  int
    20  }{
    21  	// implemented in Fails_If_Using_Self_As_Type_Name
    22  	// "case1": {
    23  	//	model: `
    24  	//	type user
    25  	//	type self
    26  	//	  relations
    27  	//		define member: [user]
    28  	//	`,
    29  	//	code: 2056,
    30  	// },
    31  	// implemented in Fails_If_Using_This_As_Type_Name
    32  	// "case2": {
    33  	//	model: `
    34  	//	type user
    35  	//	type this
    36  	//	  relations
    37  	//		define member: [user]
    38  	//	`,
    39  	//	code: 2056,
    40  	// },
    41  	// implemented in Fails_If_Using_Self_As_Relation_Name
    42  	// "case3": {
    43  	//	model: `
    44  	//	type user
    45  	//	type group
    46  	//	  relations
    47  	//		define self: [user]
    48  	//	`,
    49  	//	code: 2056,
    50  	// },
    51  	// implemented in Fails_If_Using_This_As_Relation_Name
    52  	// "case4": {
    53  	//	model: `
    54  	//	type user
    55  	//	type group
    56  	//	  relations
    57  	//		define this: [user]
    58  	//	`,
    59  	//	code: 2056,
    60  	// },
    61  	"case6": {
    62  		model: `model
    63  	schema 1.1
    64  type user
    65  type group
    66    relations
    67  	define group: group from group`,
    68  		code: 2056,
    69  	},
    70  	"case7": {
    71  		model: `model
    72  	schema 1.1
    73  type user
    74  type group
    75    relations
    76  	define parent: [group]
    77  	define viewer: viewer from parent`,
    78  		code: 2056,
    79  	},
    80  	"case8": {
    81  		model: `model
    82  	schema 1.1
    83  type group
    84    relations
    85  	define viewer: [group#viewer]`,
    86  		code: 2056,
    87  	},
    88  	"case9": {
    89  		model: `model
    90  	schema 1.1
    91  type user
    92  type org
    93    relations
    94  	define member: [user]
    95  type group
    96    relations
    97  	define parent: [org]
    98  	define viewer: viewer from parent`,
    99  		code: 2056,
   100  	},
   101  	"case10": {
   102  		model: `model
   103  	schema 1.1
   104  type user
   105  type group
   106    relations
   107  	define parent: [group]
   108  	define viewer: reader from parent`,
   109  		code: 2056,
   110  	},
   111  	"case11": {
   112  		model: `model
   113  	schema 1.1
   114  type user
   115  type org
   116  type group
   117    relations
   118  	define parent: [group]
   119  	define viewer: viewer from org`,
   120  		code: 2056,
   121  	},
   122  	"case12": {
   123  		model: `model
   124  	schema 1.1
   125  type user
   126  type org
   127  type group
   128    relations
   129  	define parent: [group]
   130  	define viewer: org from parent`,
   131  		code: 2056,
   132  	},
   133  	"case13": {
   134  		model: `model
   135  	schema 1.1
   136  type user
   137  type org
   138  type group
   139    relations
   140  	define parent: [group, group#org]`,
   141  		code: 2056,
   142  	},
   143  	"case14": {
   144  		model: `model
   145  	schema 1.1
   146  type user
   147  type org
   148    relations
   149  	define viewer: [user]
   150  type group
   151    relations
   152  	define parent: [group]
   153  	define viewer: viewer from parent`,
   154  		code: 2056,
   155  	},
   156  	"case16": {
   157  		model: `model
   158  	schema 1.1
   159  type document
   160    relations
   161  	define reader: writer
   162  	define writer: reader`,
   163  		code: 2056,
   164  	},
   165  	"case17": {
   166  		model: `model
   167  	schema 1.1
   168  type user
   169  type folder
   170    relations
   171  	define parent: [folder] or parent from parent
   172  	define viewer: [user] or viewer from parent`,
   173  		code: 2056,
   174  	},
   175  	"case18": {
   176  		model: `model
   177  	schema 1.1
   178  type user
   179  type folder
   180    relations
   181  	define root: [folder]
   182  	define parent: [folder] or root
   183  	define viewer: [user] or viewer from parent`,
   184  		code: 2056,
   185  	},
   186  	"case19": {
   187  		model: `model
   188  	schema 1.1
   189  type user
   190  type folder
   191    relations
   192  	define root: [folder]
   193  	define parent: root
   194  	define viewer: [user] or viewer from parent`,
   195  		code: 2056,
   196  	},
   197  	"case20": {
   198  		model: `model
   199  	schema 1.1
   200  type user
   201  type folder
   202    relations
   203  	define root: [folder]
   204  	define parent: [folder, folder#parent]
   205  	define viewer: [user] or viewer from parent`,
   206  		code: 2056,
   207  	},
   208  	"case21": {
   209  		model: `model
   210  	schema 1.1
   211  type user
   212  type group
   213    relations
   214  	define member: [user]
   215  	define reader: member and allowed`,
   216  		code: 2056,
   217  	},
   218  	"case22": {
   219  		model: `model
   220  	schema 1.1
   221  type user
   222  type group
   223    relations
   224  	define member: [user]
   225  	define reader: member or allowed`,
   226  		code: 2056,
   227  	},
   228  	"case23": {
   229  		model: `model
   230  	schema 1.1
   231  type user
   232  type group
   233    relations
   234  	define member: [user]
   235  	define reader: allowed but not member`,
   236  		code: 2056,
   237  	},
   238  	"case24": {
   239  		model: `model
   240  	schema 1.1
   241  type user
   242  type group
   243    relations
   244  	define member: [user]
   245  	define reader: member but not allowed`,
   246  		code: 2056,
   247  	},
   248  	//	"case25": {
   249  	//		model: `model
   250  	//	schema 1.1
   251  	// type user
   252  	// type org
   253  	//  relations
   254  	//	define member`,
   255  	//		code: 2056,
   256  	//	},
   257  	"same_type_fails": {
   258  		model: `model
   259  	schema 1.1
   260  type user
   261  type user`,
   262  		code: 2056,
   263  	},
   264  	"difference_includes_itself_in_subtract_fails": {
   265  		model: `model
   266  	schema 1.1
   267  type user
   268  type document
   269    relations
   270  	define viewer: [user] but not viewer`,
   271  		code: 2056,
   272  	},
   273  	"union_includes_itself_fails": {
   274  		model: `model
   275  	schema 1.1
   276  type user
   277  type document
   278    relations
   279  	define viewer: [user] or viewer`,
   280  		code: 2056,
   281  	},
   282  	"intersection_includes_itself_fails": {
   283  		model: `model
   284  	schema 1.1
   285  type user
   286  type document
   287    relations
   288  	define viewer: [user] and viewer`,
   289  		code: 2056,
   290  	},
   291  	"simple_model_succeeds": {
   292  		model: `model
   293  	schema 1.1
   294  type user
   295  type folder
   296    relations
   297  	define viewer: [user]
   298  type document
   299    relations
   300  	define parent: [folder]
   301  	define viewer: viewer from parent`,
   302  	},
   303  	"no_relations_succeeds": {
   304  		model: `model
   305  	schema 1.1
   306  type user`,
   307  	},
   308  	"union_may_contain_repeated_relations": {
   309  		model: `model
   310  	schema 1.1
   311  type user
   312  type document
   313    relations
   314  	define editor: [user]
   315  	define viewer: editor or editor`,
   316  	},
   317  	"intersection_may_contain_repeated_relations": {
   318  		model: `model
   319  	schema 1.1
   320  type user
   321  type document
   322    relations
   323  	define editor: [user]
   324  	define viewer: editor and editor`,
   325  	},
   326  	"exclusion_may_contain_repeated_relations": {
   327  		model: `model
   328  	schema 1.1
   329  type user
   330  type document
   331    relations
   332  	define editor: [user]
   333  	define viewer: editor but not editor`,
   334  	},
   335  	"as_long_as_one_computed_userset_type_is_valid": {
   336  		model: `model
   337  	schema 1.1
   338  type user
   339  type group
   340    relations
   341  	define parent: [group, team]
   342  	define viewer: reader from parent
   343  type team
   344    relations
   345  	define reader: [user]`,
   346  	},
   347  }
   348  
   349  // ClientInterface defines interface for running WriteAuthorizationModel tests.
   350  type ClientInterface interface {
   351  	CreateStore(ctx context.Context, in *openfgav1.CreateStoreRequest, opts ...grpc.CallOption) (*openfgav1.CreateStoreResponse, error)
   352  	WriteAuthorizationModel(ctx context.Context, in *openfgav1.WriteAuthorizationModelRequest, opts ...grpc.CallOption) (*openfgav1.WriteAuthorizationModelResponse, error)
   353  }
   354  
   355  // RunAllTests will run all write model tests.
   356  func RunAllTests(t *testing.T, client ClientInterface) {
   357  	t.Run("RunAllTests", func(t *testing.T) {
   358  		t.Run("WriteTest", func(t *testing.T) {
   359  			t.Parallel()
   360  			runTests(t, client)
   361  		})
   362  	})
   363  }
   364  
   365  func runTests(t *testing.T, client ClientInterface) {
   366  	ctx := context.Background()
   367  
   368  	for name, test := range testCases {
   369  		name := name
   370  		test := test
   371  
   372  		t.Run(name, func(t *testing.T) {
   373  			t.Parallel()
   374  			resp, err := client.CreateStore(ctx, &openfgav1.CreateStoreRequest{Name: "write_model_test"})
   375  			require.NoError(t, err)
   376  
   377  			storeID := resp.GetId()
   378  			model := parser.MustTransformDSLToProto(test.model)
   379  			_, err = client.WriteAuthorizationModel(ctx, &openfgav1.WriteAuthorizationModelRequest{
   380  				StoreId:         storeID,
   381  				SchemaVersion:   typesystem.SchemaVersion1_1,
   382  				TypeDefinitions: model.GetTypeDefinitions(),
   383  				Conditions:      model.GetConditions(),
   384  			})
   385  
   386  			if test.code == 0 {
   387  				require.NoError(t, err)
   388  			} else {
   389  				require.Error(t, err)
   390  				e, ok := status.FromError(err)
   391  				require.True(t, ok)
   392  				require.Equal(t, test.code, int(e.Code()), err)
   393  			}
   394  		})
   395  	}
   396  }