862060875b
Adds unit tests for the `AddOrganization` and `AddAPIKey` commands. These tests validate various scenarios, including success cases, handling of already existing organizations or keys, and ensuring required fields are checked. The changes enhance test coverage and ensure robustness of the command logic.
435 lines
8.0 KiB
Go
435 lines
8.0 KiB
Go
package sdlmerge
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestMergeSDLs_Success(t *testing.T) {
|
|
// Both types need to be in the same subgraph or properly federated
|
|
sdl1 := `
|
|
type User {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
|
|
type Post {
|
|
id: ID!
|
|
title: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl1)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "Post")
|
|
assert.Contains(t, result, "id")
|
|
assert.Contains(t, result, "name")
|
|
assert.Contains(t, result, "title")
|
|
}
|
|
|
|
func TestMergeSDLs_SingleSchema(t *testing.T) {
|
|
sdl := `
|
|
type Query {
|
|
hello: String
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "Query")
|
|
assert.Contains(t, result, "hello")
|
|
}
|
|
|
|
func TestMergeSDLs_EmptySchemas(t *testing.T) {
|
|
result, err := MergeSDLs()
|
|
require.NoError(t, err)
|
|
// With no schemas, result will be empty after processing
|
|
// This is valid - just verifies no crash
|
|
_ = result
|
|
}
|
|
|
|
func TestMergeSDLs_InvalidSyntax(t *testing.T) {
|
|
invalidSDL := `
|
|
type User {
|
|
id: ID!
|
|
name: String!
|
|
// Missing closing brace
|
|
`
|
|
|
|
_, err := MergeSDLs(invalidSDL)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "parse graphql document string")
|
|
}
|
|
|
|
func TestMergeSDLs_UnknownType(t *testing.T) {
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
profile: UnknownType
|
|
}
|
|
`
|
|
|
|
_, err := MergeSDLs(sdl)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "validate schema")
|
|
}
|
|
|
|
func TestMergeSDLs_DuplicateTypes_DifferentFields(t *testing.T) {
|
|
// Same type with different fields in different subgraphs - should fail
|
|
// In federation, shared types must be identical
|
|
sdl1 := `
|
|
type User {
|
|
id: ID!
|
|
}
|
|
`
|
|
sdl2 := `
|
|
type User {
|
|
name: String!
|
|
}
|
|
`
|
|
|
|
_, err := MergeSDLs(sdl1, sdl2)
|
|
require.Error(t, err)
|
|
assert.Contains(t, err.Error(), "shared type")
|
|
}
|
|
|
|
func TestMergeSDLs_ExtendType(t *testing.T) {
|
|
sdl1 := `
|
|
type User {
|
|
id: ID!
|
|
}
|
|
`
|
|
sdl2 := `
|
|
extend type User {
|
|
email: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl1, sdl2)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "id")
|
|
assert.Contains(t, result, "email")
|
|
}
|
|
|
|
func TestMergeSDLs_Scalars(t *testing.T) {
|
|
sdl := `
|
|
scalar DateTime
|
|
|
|
type Event {
|
|
id: ID!
|
|
createdAt: DateTime!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "DateTime")
|
|
assert.Contains(t, result, "Event")
|
|
}
|
|
|
|
func TestMergeSDLs_Enums(t *testing.T) {
|
|
sdl := `
|
|
enum Role {
|
|
ADMIN
|
|
USER
|
|
GUEST
|
|
}
|
|
|
|
type User {
|
|
id: ID!
|
|
role: Role!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "Role")
|
|
assert.Contains(t, result, "ADMIN")
|
|
assert.Contains(t, result, "USER")
|
|
}
|
|
|
|
func TestMergeSDLs_Interfaces(t *testing.T) {
|
|
sdl := `
|
|
interface Node {
|
|
id: ID!
|
|
}
|
|
|
|
type User implements Node {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "Node")
|
|
assert.Contains(t, result, "implements")
|
|
}
|
|
|
|
func TestMergeSDLs_Unions(t *testing.T) {
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
|
|
type Bot {
|
|
id: ID!
|
|
version: String!
|
|
}
|
|
|
|
union Actor = User | Bot
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "Actor")
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "Bot")
|
|
}
|
|
|
|
func TestMergeSDLs_InputTypes(t *testing.T) {
|
|
sdl := `
|
|
input CreateUserInput {
|
|
name: String!
|
|
email: String!
|
|
}
|
|
|
|
type Mutation {
|
|
createUser(input: CreateUserInput!): User
|
|
}
|
|
|
|
type User {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "CreateUserInput")
|
|
assert.Contains(t, result, "createUser")
|
|
}
|
|
|
|
func TestMergeSDLs_Directives(t *testing.T) {
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
name: String! @deprecated(reason: "Use fullName instead")
|
|
fullName: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "name")
|
|
assert.Contains(t, result, "fullName")
|
|
}
|
|
|
|
func TestMergeSDLs_FederationKeys(t *testing.T) {
|
|
// Federation @key directive
|
|
sdl := `
|
|
type User @key(fields: "id") {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
// @key directive should be removed during merge
|
|
assert.NotContains(t, result, "@key")
|
|
}
|
|
|
|
func TestMergeSDLs_ExternalFields(t *testing.T) {
|
|
// Federation @external directive
|
|
sdl1 := `
|
|
type User @key(fields: "id") {
|
|
id: ID!
|
|
name: String!
|
|
}
|
|
`
|
|
sdl2 := `
|
|
extend type User @key(fields: "id") {
|
|
id: ID! @external
|
|
posts: [Post!]!
|
|
}
|
|
|
|
type Post {
|
|
id: ID!
|
|
title: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl1, sdl2)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "Post")
|
|
// @external fields should be removed
|
|
assert.NotContains(t, result, "@external")
|
|
}
|
|
|
|
func TestMergeSDLs_ComplexSchema(t *testing.T) {
|
|
// Multiple subgraphs with various types - simplified to avoid cross-references
|
|
users := `
|
|
type User @key(fields: "id") {
|
|
id: ID!
|
|
username: String!
|
|
email: String!
|
|
}
|
|
|
|
type Query {
|
|
user(id: ID!): User
|
|
users: [User!]!
|
|
}
|
|
`
|
|
|
|
posts := `
|
|
extend type User @key(fields: "id") {
|
|
id: ID! @external
|
|
posts: [Post!]!
|
|
}
|
|
|
|
type Post @key(fields: "id") {
|
|
id: ID!
|
|
title: String!
|
|
content: String!
|
|
}
|
|
|
|
extend type Query {
|
|
post(id: ID!): Post
|
|
posts: [Post!]!
|
|
}
|
|
`
|
|
|
|
comments := `
|
|
extend type Post @key(fields: "id") {
|
|
id: ID! @external
|
|
comments: [Comment!]!
|
|
}
|
|
|
|
type Comment {
|
|
id: ID!
|
|
text: String!
|
|
}
|
|
|
|
extend type Query {
|
|
comment(id: ID!): Comment
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(users, posts, comments)
|
|
require.NoError(t, err)
|
|
|
|
// Verify all types are present
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "Post")
|
|
assert.Contains(t, result, "Comment")
|
|
assert.Contains(t, result, "Query")
|
|
|
|
// Verify fields from all subgraphs
|
|
assert.Contains(t, result, "username")
|
|
assert.Contains(t, result, "posts")
|
|
assert.Contains(t, result, "comments")
|
|
}
|
|
|
|
func TestMergeSDLs_EmptyTypeDefinition(t *testing.T) {
|
|
sdl := `
|
|
type Empty {}
|
|
`
|
|
|
|
_, err := MergeSDLs(sdl)
|
|
require.Error(t, err)
|
|
// Empty types are invalid in GraphQL
|
|
assert.Contains(t, err.Error(), "empty body")
|
|
}
|
|
|
|
func TestMergeSDLs_MultipleValidationErrors(t *testing.T) {
|
|
// Schema with multiple errors
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
profile: NonExistentType1
|
|
settings: NonExistentType2
|
|
}
|
|
`
|
|
|
|
_, err := MergeSDLs(sdl)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestMergeSDLs_ListTypes(t *testing.T) {
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
tags: [String!]!
|
|
friends: [User!]
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "tags")
|
|
assert.Contains(t, result, "friends")
|
|
}
|
|
|
|
func TestMergeSDLs_NonNullTypes(t *testing.T) {
|
|
sdl := `
|
|
type User {
|
|
id: ID!
|
|
name: String!
|
|
email: String
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
assert.Contains(t, result, "id")
|
|
assert.Contains(t, result, "name")
|
|
assert.Contains(t, result, "email")
|
|
}
|
|
|
|
func TestMergeSDLs_Comments(t *testing.T) {
|
|
sdl := `
|
|
# This is a user type
|
|
type User {
|
|
# User ID
|
|
id: ID!
|
|
# User name
|
|
name: String!
|
|
}
|
|
`
|
|
|
|
result, err := MergeSDLs(sdl)
|
|
require.NoError(t, err)
|
|
assert.Contains(t, result, "User")
|
|
}
|
|
|
|
func TestMergeSDLs_LargeSchema(t *testing.T) {
|
|
// Test with a reasonably large schema to ensure performance
|
|
var sdlBuilder strings.Builder
|
|
for i := 0; i < 50; i++ {
|
|
sdlBuilder.WriteString("type Type")
|
|
sdlBuilder.WriteString(strings.Repeat(string(rune('A'+i%26)), 1))
|
|
sdlBuilder.WriteString(string(rune('0' + i/26)))
|
|
sdlBuilder.WriteString(" { id: ID }\n")
|
|
}
|
|
|
|
result, err := MergeSDLs(sdlBuilder.String())
|
|
require.NoError(t, err)
|
|
|
|
// Verify some types are present
|
|
assert.Contains(t, result, "TypeA0")
|
|
assert.Contains(t, result, "TypeB0")
|
|
assert.Contains(t, result, "TypeC0")
|
|
}
|