github.com/speakeasy-api/sdk-gen-config@v1.14.2/workflow/workflow_test.go (about)

     1  package workflow_test
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/speakeasy-api/sdk-gen-config/workflow"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func TestWorkflow_Load_Success(t *testing.T) {
    15  	type args struct {
    16  		workflowLocation string
    17  		workflowContents string
    18  		workingDir       string
    19  	}
    20  	tests := []struct {
    21  		name string
    22  		args args
    23  		want *workflow.Workflow
    24  	}{
    25  		{
    26  			name: "loads simple workflow file",
    27  			args: args{
    28  				workflowLocation: "test/.speakeasy",
    29  				workflowContents: `workflowVersion: 1.0.0
    30  sources:
    31    testSource:
    32      inputs:
    33        - location: "./openapi.yaml"
    34  targets:
    35    typescript:
    36      target: typescript
    37      source: testSource
    38  `,
    39  				workingDir: "test",
    40  			},
    41  			want: &workflow.Workflow{
    42  				Version: "1.0.0",
    43  				Sources: map[string]workflow.Source{
    44  					"testSource": {
    45  						Inputs: []workflow.Document{
    46  							{
    47  								Location: "./openapi.yaml",
    48  							},
    49  						},
    50  					},
    51  				},
    52  				Targets: map[string]workflow.Target{
    53  					"typescript": {
    54  						Target: "typescript",
    55  						Source: "testSource",
    56  					},
    57  				},
    58  			},
    59  		},
    60  	}
    61  	for _, tt := range tests {
    62  		t.Run(tt.name, func(t *testing.T) {
    63  			basePath, err := os.MkdirTemp("", "workflow*")
    64  			require.NoError(t, err)
    65  			defer os.RemoveAll(basePath)
    66  
    67  			err = createTempFile(filepath.Join(basePath, tt.args.workflowLocation), "workflow.yaml", tt.args.workflowContents)
    68  			require.NoError(t, err)
    69  
    70  			workflowFile, workflowPath, err := workflow.Load(filepath.Join(basePath, tt.args.workingDir))
    71  			require.NoError(t, err)
    72  
    73  			assert.Equal(t, tt.want, workflowFile)
    74  			assert.Contains(t, workflowPath, filepath.Join(tt.args.workflowLocation, "workflow.yaml"))
    75  		})
    76  	}
    77  }
    78  
    79  func TestWorkflow_Validate(t *testing.T) {
    80  	type args struct {
    81  		supportedLangs []string
    82  		workflow       *workflow.Workflow
    83  		createSource   bool
    84  	}
    85  	tests := []struct {
    86  		name    string
    87  		args    args
    88  		wantErr error
    89  	}{
    90  		{
    91  			name: "simple workflow file with target successfully validates",
    92  			args: args{
    93  				supportedLangs: []string{"typescript"},
    94  				workflow: &workflow.Workflow{
    95  					Version: workflow.WorkflowVersion,
    96  					Targets: map[string]workflow.Target{
    97  						"typescript": {
    98  							Target: "typescript",
    99  							Source: "./openapi.yaml",
   100  						},
   101  					},
   102  				},
   103  				createSource: true,
   104  			},
   105  			wantErr: nil,
   106  		},
   107  		{
   108  			name: "simple workflow file with source successfully validates",
   109  			args: args{
   110  				workflow: &workflow.Workflow{
   111  					Version: workflow.WorkflowVersion,
   112  					Sources: map[string]workflow.Source{
   113  						"testSource": {
   114  							Inputs: []workflow.Document{
   115  								{
   116  									Location: "./openapi.yaml",
   117  								},
   118  							},
   119  						},
   120  					},
   121  				},
   122  				createSource: true,
   123  			},
   124  			wantErr: nil,
   125  		},
   126  		{
   127  			name: "workflow successfully validates",
   128  			args: args{
   129  				supportedLangs: []string{"typescript"},
   130  				workflow: &workflow.Workflow{
   131  					Version: workflow.WorkflowVersion,
   132  					Sources: map[string]workflow.Source{
   133  						"testSource": {
   134  							Inputs: []workflow.Document{
   135  								{
   136  									Location: "./openapi.yaml",
   137  								},
   138  							},
   139  						},
   140  					},
   141  					Targets: map[string]workflow.Target{
   142  						"typescript": {
   143  							Target: "typescript",
   144  							Source: "testSource",
   145  						},
   146  					},
   147  				},
   148  				createSource: true,
   149  			},
   150  			wantErr: nil,
   151  		},
   152  		{
   153  			name: "workflow version is not supported",
   154  			args: args{
   155  				supportedLangs: []string{"typescript"},
   156  				workflow: &workflow.Workflow{
   157  					Version: "0.0.0",
   158  				},
   159  			},
   160  			wantErr: fmt.Errorf("unsupported workflow version: 0.0.0"),
   161  		},
   162  		{
   163  			name: "workflow fails to validate with no targets or sources",
   164  			args: args{
   165  				supportedLangs: []string{"typescript"},
   166  				workflow: &workflow.Workflow{
   167  					Version: workflow.WorkflowVersion,
   168  				},
   169  			},
   170  			wantErr: fmt.Errorf("no sources or targets found"),
   171  		},
   172  		{
   173  			name: "workflow fails if target is invalid",
   174  			args: args{
   175  				supportedLangs: []string{"typescript"},
   176  				workflow: &workflow.Workflow{
   177  					Version: workflow.WorkflowVersion,
   178  					Targets: map[string]workflow.Target{
   179  						"typescript": {},
   180  					},
   181  				},
   182  			},
   183  			wantErr: fmt.Errorf("failed to validate target typescript: target is required"),
   184  		},
   185  		{
   186  			name: "workflow fails to validate if source is invalid",
   187  			args: args{
   188  				supportedLangs: []string{"typescript"},
   189  				workflow: &workflow.Workflow{
   190  					Version: workflow.WorkflowVersion,
   191  					Sources: map[string]workflow.Source{
   192  						"testSource": {
   193  							Inputs: []workflow.Document{
   194  								{
   195  									Location: "http://example.com/openapi.yaml",
   196  								},
   197  							},
   198  						},
   199  						"testSource2": {
   200  							Inputs: []workflow.Document{
   201  								{
   202  									Location: "./openapi1.yaml",
   203  									Auth: &workflow.Auth{
   204  										Header: "Authorization",
   205  										Secret: "$AUTH_TOKEN",
   206  									},
   207  								},
   208  							},
   209  						},
   210  					},
   211  					Targets: map[string]workflow.Target{
   212  						"typescript": {
   213  							Target: "typescript",
   214  							Source: "testSource",
   215  						},
   216  					},
   217  				},
   218  				createSource: true,
   219  			},
   220  			wantErr: fmt.Errorf("failed to validate source testSource2: failed to validate input 0: auth is only supported for remote documents"),
   221  		},
   222  	}
   223  	for _, tt := range tests {
   224  		t.Run(tt.name, func(t *testing.T) {
   225  			if tt.args.createSource {
   226  				if len(tt.args.workflow.Sources) > 0 {
   227  					for _, source := range tt.args.workflow.Sources {
   228  						workDir, err := createLocalFiles(source)
   229  						require.NoError(t, err)
   230  						defer os.RemoveAll(workDir)
   231  
   232  						err = os.Chdir(workDir)
   233  						require.NoError(t, err)
   234  					}
   235  				} else {
   236  					workDir, err := os.MkdirTemp("", "workflow*")
   237  					require.NoError(t, err)
   238  
   239  					for _, target := range tt.args.workflow.Targets {
   240  						err = createEmptyFile(filepath.Join(workDir, target.Source))
   241  						require.NoError(t, err)
   242  					}
   243  
   244  					err = os.Chdir(workDir)
   245  					require.NoError(t, err)
   246  				}
   247  			}
   248  
   249  			err := tt.args.workflow.Validate(tt.args.supportedLangs)
   250  			if tt.wantErr == nil {
   251  				assert.NoError(t, err)
   252  			} else {
   253  				assert.EqualError(t, err, tt.wantErr.Error())
   254  			}
   255  		})
   256  	}
   257  }
   258  
   259  func createTempFile(dir string, fileName, contents string) error {
   260  	if err := os.MkdirAll(dir, os.ModePerm); err != nil {
   261  		return err
   262  	}
   263  
   264  	if contents != "" {
   265  		tmpFile := filepath.Join(dir, fileName)
   266  		if err := os.WriteFile(tmpFile, []byte(contents), os.ModePerm); err != nil {
   267  			return err
   268  		}
   269  	}
   270  
   271  	return nil
   272  }