Added Graphql
This commit is contained in:
362
pkg/readers/graphql/reader_test.go
Normal file
362
pkg/readers/graphql/reader_test.go
Normal file
@@ -0,0 +1,362 @@
|
||||
package graphql
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
||||
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
||||
)
|
||||
|
||||
func TestReader_ReadDatabase_Simple(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "simple.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
if len(db.Schemas) == 0 {
|
||||
t.Fatal("Expected at least one schema")
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
if schema.Name != "public" {
|
||||
t.Errorf("Expected schema name 'public', got '%s'", schema.Name)
|
||||
}
|
||||
|
||||
if len(schema.Tables) != 1 {
|
||||
t.Fatalf("Expected 1 table, got %d", len(schema.Tables))
|
||||
}
|
||||
|
||||
userTable := schema.Tables[0]
|
||||
if userTable.Name != "User" {
|
||||
t.Errorf("Expected table name 'User', got '%s'", userTable.Name)
|
||||
}
|
||||
|
||||
// Verify columns
|
||||
expectedColumns := map[string]struct {
|
||||
sqlType string
|
||||
notNull bool
|
||||
isPK bool
|
||||
}{
|
||||
"id": {"bigint", true, true},
|
||||
"email": {"text", true, false},
|
||||
"name": {"text", false, false},
|
||||
"age": {"integer", false, false},
|
||||
"active": {"boolean", true, false},
|
||||
}
|
||||
|
||||
if len(userTable.Columns) != len(expectedColumns) {
|
||||
t.Fatalf("Expected %d columns, got %d", len(expectedColumns), len(userTable.Columns))
|
||||
}
|
||||
|
||||
for colName, expected := range expectedColumns {
|
||||
col, exists := userTable.Columns[colName]
|
||||
if !exists {
|
||||
t.Errorf("Expected column '%s' not found", colName)
|
||||
continue
|
||||
}
|
||||
|
||||
if col.Type != expected.sqlType {
|
||||
t.Errorf("Column '%s': expected type '%s', got '%s'", colName, expected.sqlType, col.Type)
|
||||
}
|
||||
|
||||
if col.NotNull != expected.notNull {
|
||||
t.Errorf("Column '%s': expected NotNull=%v, got %v", colName, expected.notNull, col.NotNull)
|
||||
}
|
||||
|
||||
if col.IsPrimaryKey != expected.isPK {
|
||||
t.Errorf("Column '%s': expected IsPrimaryKey=%v, got %v", colName, expected.isPK, col.IsPrimaryKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadDatabase_WithRelations(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "relations.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
|
||||
if len(schema.Tables) != 2 {
|
||||
t.Fatalf("Expected 2 tables, got %d", len(schema.Tables))
|
||||
}
|
||||
|
||||
// Find Post table (should have FK to User)
|
||||
var postTable *models.Table
|
||||
for _, table := range schema.Tables {
|
||||
if table.Name == "Post" {
|
||||
postTable = table
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if postTable == nil {
|
||||
t.Fatal("Post table not found")
|
||||
}
|
||||
|
||||
// Verify authorId FK column was created
|
||||
authorIdCol, exists := postTable.Columns["authorId"]
|
||||
if !exists {
|
||||
t.Fatal("Expected 'authorId' FK column not found in Post table")
|
||||
}
|
||||
|
||||
if authorIdCol.Type != "bigint" {
|
||||
t.Errorf("Expected authorId type 'bigint', got '%s'", authorIdCol.Type)
|
||||
}
|
||||
|
||||
if !authorIdCol.NotNull {
|
||||
t.Error("Expected authorId to be NOT NULL")
|
||||
}
|
||||
|
||||
// Verify FK constraint
|
||||
fkConstraintFound := false
|
||||
for _, constraint := range postTable.Constraints {
|
||||
if constraint.Type == models.ForeignKeyConstraint {
|
||||
if constraint.ReferencedTable == "User" && len(constraint.Columns) > 0 && constraint.Columns[0] == "authorId" {
|
||||
fkConstraintFound = true
|
||||
if constraint.OnDelete != "CASCADE" {
|
||||
t.Errorf("Expected OnDelete CASCADE, got %s", constraint.OnDelete)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !fkConstraintFound {
|
||||
t.Error("Foreign key constraint from Post to User not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadDatabase_WithEnums(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "enums.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
|
||||
if len(schema.Enums) != 1 {
|
||||
t.Fatalf("Expected 1 enum, got %d", len(schema.Enums))
|
||||
}
|
||||
|
||||
roleEnum := schema.Enums[0]
|
||||
if roleEnum.Name != "Role" {
|
||||
t.Errorf("Expected enum name 'Role', got '%s'", roleEnum.Name)
|
||||
}
|
||||
|
||||
expectedValues := []string{"ADMIN", "USER", "GUEST"}
|
||||
if len(roleEnum.Values) != len(expectedValues) {
|
||||
t.Fatalf("Expected %d enum values, got %d", len(expectedValues), len(roleEnum.Values))
|
||||
}
|
||||
|
||||
for i, expected := range expectedValues {
|
||||
if roleEnum.Values[i] != expected {
|
||||
t.Errorf("Expected enum value '%s' at index %d, got '%s'", expected, i, roleEnum.Values[i])
|
||||
}
|
||||
}
|
||||
|
||||
// Verify role column in User table
|
||||
userTable := schema.Tables[0]
|
||||
roleCol, exists := userTable.Columns["role"]
|
||||
if !exists {
|
||||
t.Fatal("Expected 'role' column not found")
|
||||
}
|
||||
|
||||
if roleCol.Type != "Role" {
|
||||
t.Errorf("Expected role type 'Role', got '%s'", roleCol.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadDatabase_CustomScalars(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "custom_scalars.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
userTable := schema.Tables[0]
|
||||
|
||||
// Verify custom scalar mappings
|
||||
expectedTypes := map[string]string{
|
||||
"createdAt": "timestamp",
|
||||
"metadata": "jsonb",
|
||||
"birthDate": "date",
|
||||
}
|
||||
|
||||
for colName, expectedType := range expectedTypes {
|
||||
col, exists := userTable.Columns[colName]
|
||||
if !exists {
|
||||
t.Errorf("Expected column '%s' not found", colName)
|
||||
continue
|
||||
}
|
||||
|
||||
if col.Type != expectedType {
|
||||
t.Errorf("Column '%s': expected type '%s', got '%s'", colName, expectedType, col.Type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadDatabase_UUIDMetadata(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "simple.graphql"),
|
||||
Metadata: map[string]interface{}{
|
||||
"idType": "uuid",
|
||||
},
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
userTable := schema.Tables[0]
|
||||
|
||||
idCol, exists := userTable.Columns["id"]
|
||||
if !exists {
|
||||
t.Fatal("Expected 'id' column not found")
|
||||
}
|
||||
|
||||
if idCol.Type != "uuid" {
|
||||
t.Errorf("Expected id type 'uuid' with metadata, got '%s'", idCol.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadDatabase_Complex(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "complex.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
db, err := reader.ReadDatabase()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadDatabase() error = %v", err)
|
||||
}
|
||||
|
||||
schema := db.Schemas[0]
|
||||
|
||||
// Should have 5 tables: User, Profile, Post, Tag, and PostTag (join table)
|
||||
expectedTableCount := 5
|
||||
if len(schema.Tables) != expectedTableCount {
|
||||
t.Fatalf("Expected %d tables, got %d", expectedTableCount, len(schema.Tables))
|
||||
}
|
||||
|
||||
// Verify PostTag join table exists (many-to-many between Post and Tag)
|
||||
var joinTable *models.Table
|
||||
for _, table := range schema.Tables {
|
||||
if table.Name == "PostTag" {
|
||||
joinTable = table
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if joinTable == nil {
|
||||
t.Fatal("Expected PostTag join table not found")
|
||||
}
|
||||
|
||||
// Verify join table has both FK columns
|
||||
if _, exists := joinTable.Columns["postId"]; !exists {
|
||||
t.Error("Expected 'postId' column in PostTag join table")
|
||||
}
|
||||
|
||||
if _, exists := joinTable.Columns["tagId"]; !exists {
|
||||
t.Error("Expected 'tagId' column in PostTag join table")
|
||||
}
|
||||
|
||||
// Verify composite primary key
|
||||
pkFound := false
|
||||
for _, constraint := range joinTable.Constraints {
|
||||
if constraint.Type == models.PrimaryKeyConstraint {
|
||||
if len(constraint.Columns) == 2 {
|
||||
pkFound = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !pkFound {
|
||||
t.Error("Expected composite primary key in PostTag join table")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadSchema(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "simple.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
schema, err := reader.ReadSchema()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadSchema() error = %v", err)
|
||||
}
|
||||
|
||||
if schema.Name != "public" {
|
||||
t.Errorf("Expected schema name 'public', got '%s'", schema.Name)
|
||||
}
|
||||
|
||||
if len(schema.Tables) != 1 {
|
||||
t.Errorf("Expected 1 table, got %d", len(schema.Tables))
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_ReadTable(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: filepath.Join("..", "..", "..", "tests", "assets", "graphql", "simple.graphql"),
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
table, err := reader.ReadTable()
|
||||
if err != nil {
|
||||
t.Fatalf("ReadTable() error = %v", err)
|
||||
}
|
||||
|
||||
if table.Name != "User" {
|
||||
t.Errorf("Expected table name 'User', got '%s'", table.Name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_InvalidPath(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: "/nonexistent/path.graphql",
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
_, err := reader.ReadDatabase()
|
||||
if err == nil {
|
||||
t.Error("Expected error for invalid path, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestReader_EmptyPath(t *testing.T) {
|
||||
opts := &readers.ReaderOptions{
|
||||
FilePath: "",
|
||||
}
|
||||
|
||||
reader := NewReader(opts)
|
||||
_, err := reader.ReadDatabase()
|
||||
if err == nil {
|
||||
t.Error("Expected error for empty path, got nil")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user