github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/openstack/openstack_test.go (about)

     1  package openstack_test
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/fastly/go-fastly/v9/fastly"
     8  
     9  	"github.com/fastly/cli/pkg/argparser"
    10  	"github.com/fastly/cli/pkg/commands/logging/openstack"
    11  	"github.com/fastly/cli/pkg/config"
    12  	"github.com/fastly/cli/pkg/errors"
    13  	"github.com/fastly/cli/pkg/global"
    14  	"github.com/fastly/cli/pkg/manifest"
    15  	"github.com/fastly/cli/pkg/mock"
    16  	"github.com/fastly/cli/pkg/testutil"
    17  )
    18  
    19  func TestCreateOpenstackInput(t *testing.T) {
    20  	for _, testcase := range []struct {
    21  		name      string
    22  		cmd       *openstack.CreateCommand
    23  		want      *fastly.CreateOpenstackInput
    24  		wantError string
    25  	}{
    26  		{
    27  			name: "required values set flag serviceID",
    28  			cmd:  createCommandRequired(),
    29  			want: &fastly.CreateOpenstackInput{
    30  				ServiceID:      "123",
    31  				ServiceVersion: 4,
    32  				Name:           fastly.ToPointer("log"),
    33  				BucketName:     fastly.ToPointer("bucket"),
    34  				AccessKey:      fastly.ToPointer("access"),
    35  				User:           fastly.ToPointer("user"),
    36  				URL:            fastly.ToPointer("https://example.com"),
    37  			},
    38  		},
    39  		{
    40  			name: "all values set flag serviceID",
    41  			cmd:  createCommandAll(),
    42  			want: &fastly.CreateOpenstackInput{
    43  				ServiceID:         "123",
    44  				ServiceVersion:    4,
    45  				Name:              fastly.ToPointer("log"),
    46  				BucketName:        fastly.ToPointer("bucket"),
    47  				AccessKey:         fastly.ToPointer("access"),
    48  				User:              fastly.ToPointer("user"),
    49  				URL:               fastly.ToPointer("https://example.com"),
    50  				Path:              fastly.ToPointer("/log"),
    51  				Period:            fastly.ToPointer(3600),
    52  				Format:            fastly.ToPointer(`%h %l %u %t "%r" %>s %b`),
    53  				MessageType:       fastly.ToPointer("classic"),
    54  				FormatVersion:     fastly.ToPointer(2),
    55  				ResponseCondition: fastly.ToPointer("Prevent default logging"),
    56  				TimestampFormat:   fastly.ToPointer("%Y-%m-%dT%H:%M:%S.000"),
    57  				Placement:         fastly.ToPointer("none"),
    58  				PublicKey:         fastly.ToPointer(pgpPublicKey()),
    59  				CompressionCodec:  fastly.ToPointer("zstd"),
    60  			},
    61  		},
    62  		{
    63  			name:      "error missing serviceID",
    64  			cmd:       createCommandMissingServiceID(),
    65  			want:      nil,
    66  			wantError: errors.ErrNoServiceID.Error(),
    67  		},
    68  	} {
    69  		t.Run(testcase.name, func(t *testing.T) {
    70  			var bs []byte
    71  			out := bytes.NewBuffer(bs)
    72  			verboseMode := true
    73  
    74  			serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{
    75  				AutoCloneFlag:      testcase.cmd.AutoClone,
    76  				APIClient:          testcase.cmd.Globals.APIClient,
    77  				Manifest:           testcase.cmd.Manifest,
    78  				Out:                out,
    79  				ServiceVersionFlag: testcase.cmd.ServiceVersion,
    80  				VerboseMode:        verboseMode,
    81  			})
    82  
    83  			switch {
    84  			case err != nil && testcase.wantError == "":
    85  				t.Fatalf("unexpected error getting service details: %v", err)
    86  				return
    87  			case err != nil && testcase.wantError != "":
    88  				testutil.AssertErrorContains(t, err, testcase.wantError)
    89  				return
    90  			case err == nil && testcase.wantError != "":
    91  				t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number)
    92  			case err == nil && testcase.wantError == "":
    93  				have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number))
    94  				testutil.AssertErrorContains(t, err, testcase.wantError)
    95  				testutil.AssertEqual(t, testcase.want, have)
    96  			}
    97  		})
    98  	}
    99  }
   100  
   101  func TestUpdateOpenstackInput(t *testing.T) {
   102  	scenarios := []struct {
   103  		name      string
   104  		cmd       *openstack.UpdateCommand
   105  		api       mock.API
   106  		want      *fastly.UpdateOpenstackInput
   107  		wantError string
   108  	}{
   109  		{
   110  			name: "all values set flag serviceID",
   111  			cmd:  updateCommandAll(),
   112  			api: mock.API{
   113  				ListVersionsFn: testutil.ListVersions,
   114  				CloneVersionFn: testutil.CloneVersionResult(4),
   115  				GetOpenstackFn: getOpenstackOK,
   116  			},
   117  			want: &fastly.UpdateOpenstackInput{
   118  				ServiceID:         "123",
   119  				ServiceVersion:    4,
   120  				Name:              "log",
   121  				NewName:           fastly.ToPointer("new1"),
   122  				BucketName:        fastly.ToPointer("new2"),
   123  				User:              fastly.ToPointer("new3"),
   124  				AccessKey:         fastly.ToPointer("new4"),
   125  				URL:               fastly.ToPointer("new5"),
   126  				Path:              fastly.ToPointer("new6"),
   127  				Period:            fastly.ToPointer(3601),
   128  				GzipLevel:         fastly.ToPointer(0),
   129  				Format:            fastly.ToPointer("new7"),
   130  				FormatVersion:     fastly.ToPointer(3),
   131  				ResponseCondition: fastly.ToPointer("new8"),
   132  				MessageType:       fastly.ToPointer("new9"),
   133  				TimestampFormat:   fastly.ToPointer("new10"),
   134  				Placement:         fastly.ToPointer("new11"),
   135  				PublicKey:         fastly.ToPointer("new12"),
   136  				CompressionCodec:  fastly.ToPointer("new13"),
   137  			},
   138  		},
   139  		{
   140  			name: "no updates",
   141  			cmd:  updateCommandNoUpdates(),
   142  			api: mock.API{
   143  				ListVersionsFn: testutil.ListVersions,
   144  				CloneVersionFn: testutil.CloneVersionResult(4),
   145  				GetOpenstackFn: getOpenstackOK,
   146  			},
   147  			want: &fastly.UpdateOpenstackInput{
   148  				ServiceID:      "123",
   149  				ServiceVersion: 4,
   150  				Name:           "log",
   151  			},
   152  		},
   153  		{
   154  			name:      "error missing serviceID",
   155  			cmd:       updateCommandMissingServiceID(),
   156  			want:      nil,
   157  			wantError: errors.ErrNoServiceID.Error(),
   158  		},
   159  	}
   160  	for testcaseIdx := range scenarios {
   161  		testcase := &scenarios[testcaseIdx]
   162  		t.Run(testcase.name, func(t *testing.T) {
   163  			testcase.cmd.Globals.APIClient = testcase.api
   164  
   165  			var bs []byte
   166  			out := bytes.NewBuffer(bs)
   167  			verboseMode := true
   168  
   169  			serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{
   170  				AutoCloneFlag:      testcase.cmd.AutoClone,
   171  				APIClient:          testcase.api,
   172  				Manifest:           testcase.cmd.Manifest,
   173  				Out:                out,
   174  				ServiceVersionFlag: testcase.cmd.ServiceVersion,
   175  				VerboseMode:        verboseMode,
   176  			})
   177  
   178  			switch {
   179  			case err != nil && testcase.wantError == "":
   180  				t.Fatalf("unexpected error getting service details: %v", err)
   181  				return
   182  			case err != nil && testcase.wantError != "":
   183  				testutil.AssertErrorContains(t, err, testcase.wantError)
   184  				return
   185  			case err == nil && testcase.wantError != "":
   186  				t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number)
   187  			case err == nil && testcase.wantError == "":
   188  				have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number))
   189  				testutil.AssertErrorContains(t, err, testcase.wantError)
   190  				testutil.AssertEqual(t, testcase.want, have)
   191  			}
   192  		})
   193  	}
   194  }
   195  
   196  func createCommandRequired() *openstack.CreateCommand {
   197  	var b bytes.Buffer
   198  
   199  	g := global.Data{
   200  		Config: config.File{},
   201  		Env:    config.Environment{},
   202  		Output: &b,
   203  	}
   204  	g.APIClient, _ = mock.APIClient(mock.API{
   205  		ListVersionsFn: testutil.ListVersions,
   206  		CloneVersionFn: testutil.CloneVersionResult(4),
   207  	})("token", "endpoint", false)
   208  
   209  	return &openstack.CreateCommand{
   210  		Base: argparser.Base{
   211  			Globals: &g,
   212  		},
   213  		Manifest: manifest.Data{
   214  			Flag: manifest.Flag{
   215  				ServiceID: "123",
   216  			},
   217  		},
   218  		ServiceVersion: argparser.OptionalServiceVersion{
   219  			OptionalString: argparser.OptionalString{Value: "1"},
   220  		},
   221  		AutoClone: argparser.OptionalAutoClone{
   222  			OptionalBool: argparser.OptionalBool{
   223  				Optional: argparser.Optional{
   224  					WasSet: true,
   225  				},
   226  				Value: true,
   227  			},
   228  		},
   229  		EndpointName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"},
   230  		BucketName:   argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "bucket"},
   231  		AccessKey:    argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "access"},
   232  		User:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"},
   233  		URL:          argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "https://example.com"},
   234  	}
   235  }
   236  
   237  func createCommandAll() *openstack.CreateCommand {
   238  	var b bytes.Buffer
   239  
   240  	g := global.Data{
   241  		Config: config.File{},
   242  		Env:    config.Environment{},
   243  		Output: &b,
   244  	}
   245  	g.APIClient, _ = mock.APIClient(mock.API{
   246  		ListVersionsFn: testutil.ListVersions,
   247  		CloneVersionFn: testutil.CloneVersionResult(4),
   248  	})("token", "endpoint", false)
   249  
   250  	return &openstack.CreateCommand{
   251  		Base: argparser.Base{
   252  			Globals: &g,
   253  		},
   254  		Manifest: manifest.Data{
   255  			Flag: manifest.Flag{
   256  				ServiceID: "123",
   257  			},
   258  		},
   259  		ServiceVersion: argparser.OptionalServiceVersion{
   260  			OptionalString: argparser.OptionalString{Value: "1"},
   261  		},
   262  		AutoClone: argparser.OptionalAutoClone{
   263  			OptionalBool: argparser.OptionalBool{
   264  				Optional: argparser.Optional{
   265  					WasSet: true,
   266  				},
   267  				Value: true,
   268  			},
   269  		},
   270  		EndpointName:      argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"},
   271  		BucketName:        argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "bucket"},
   272  		AccessKey:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "access"},
   273  		User:              argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"},
   274  		URL:               argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "https://example.com"},
   275  		Path:              argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "/log"},
   276  		Period:            argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3600},
   277  		Format:            argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: `%h %l %u %t "%r" %>s %b`},
   278  		FormatVersion:     argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 2},
   279  		ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "Prevent default logging"},
   280  		TimestampFormat:   argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "%Y-%m-%dT%H:%M:%S.000"},
   281  		Placement:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "none"},
   282  		MessageType:       argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "classic"},
   283  		PublicKey:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: pgpPublicKey()},
   284  		CompressionCodec:  argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "zstd"},
   285  	}
   286  }
   287  
   288  func createCommandMissingServiceID() *openstack.CreateCommand {
   289  	res := createCommandAll()
   290  	res.Manifest = manifest.Data{}
   291  	return res
   292  }
   293  
   294  func updateCommandNoUpdates() *openstack.UpdateCommand {
   295  	var b bytes.Buffer
   296  
   297  	g := global.Data{
   298  		Config: config.File{},
   299  		Env:    config.Environment{},
   300  		Output: &b,
   301  	}
   302  
   303  	return &openstack.UpdateCommand{
   304  		Base: argparser.Base{
   305  			Globals: &g,
   306  		},
   307  		Manifest: manifest.Data{
   308  			Flag: manifest.Flag{
   309  				ServiceID: "123",
   310  			},
   311  		},
   312  		EndpointName: "log",
   313  		ServiceVersion: argparser.OptionalServiceVersion{
   314  			OptionalString: argparser.OptionalString{Value: "1"},
   315  		},
   316  		AutoClone: argparser.OptionalAutoClone{
   317  			OptionalBool: argparser.OptionalBool{
   318  				Optional: argparser.Optional{
   319  					WasSet: true,
   320  				},
   321  				Value: true,
   322  			},
   323  		},
   324  	}
   325  }
   326  
   327  func updateCommandAll() *openstack.UpdateCommand {
   328  	var b bytes.Buffer
   329  
   330  	g := global.Data{
   331  		Config: config.File{},
   332  		Env:    config.Environment{},
   333  		Output: &b,
   334  	}
   335  
   336  	return &openstack.UpdateCommand{
   337  		Base: argparser.Base{
   338  			Globals: &g,
   339  		},
   340  		Manifest: manifest.Data{
   341  			Flag: manifest.Flag{
   342  				ServiceID: "123",
   343  			},
   344  		},
   345  		EndpointName: "log",
   346  		ServiceVersion: argparser.OptionalServiceVersion{
   347  			OptionalString: argparser.OptionalString{Value: "1"},
   348  		},
   349  		AutoClone: argparser.OptionalAutoClone{
   350  			OptionalBool: argparser.OptionalBool{
   351  				Optional: argparser.Optional{
   352  					WasSet: true,
   353  				},
   354  				Value: true,
   355  			},
   356  		},
   357  		NewName:           argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new1"},
   358  		BucketName:        argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new2"},
   359  		User:              argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new3"},
   360  		AccessKey:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new4"},
   361  		URL:               argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new5"},
   362  		Path:              argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new6"},
   363  		Period:            argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3601},
   364  		GzipLevel:         argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 0},
   365  		Format:            argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new7"},
   366  		FormatVersion:     argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3},
   367  		ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new8"},
   368  		MessageType:       argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new9"},
   369  		TimestampFormat:   argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new10"},
   370  		Placement:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new11"},
   371  		PublicKey:         argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new12"},
   372  		CompressionCodec:  argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new13"},
   373  	}
   374  }
   375  
   376  func updateCommandMissingServiceID() *openstack.UpdateCommand {
   377  	res := updateCommandAll()
   378  	res.Manifest = manifest.Data{}
   379  	return res
   380  }