func TestValidate(t *testing.T) { // No key-value env := EnvironmentItemModel{ OptionsKey: EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), Description: pointers.NewStringPtr("test_description"), Summary: pointers.NewStringPtr("test_summary"), ValueOptions: []string{"test_key2", "test_value2"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(true), IsDontChangeValue: pointers.NewBoolPtr(false), }, } require.NotEqual(t, nil, env.Validate()) // Empty key env = EnvironmentItemModel{ "": "test_value", } require.NotEqual(t, nil, env.Validate()) // Valid env env = EnvironmentItemModel{ "test_key": "test_value", } require.Equal(t, nil, env.Validate()) }
// Convert ... func (oldStep StepModel) Convert() (stepmanModels.StepModel, error) { inputs, err := oldStep.getInputEnvironments() if err != nil { return stepmanModels.StepModel{}, err } outputs, err := oldStep.getOutputEnvironments() if err != nil { return stepmanModels.StepModel{}, err } newStep := stepmanModels.StepModel{ Title: pointers.NewStringPtr(oldStep.Name), Description: pointers.NewStringPtr(oldStep.Description), Website: pointers.NewStringPtr(oldStep.Website), Source: oldStep.getSource(), HostOsTags: oldStep.HostOsTags, ProjectTypeTags: oldStep.ProjectTypeTags, TypeTags: oldStep.TypeTags, IsRequiresAdminUser: pointers.NewBoolPtr(oldStep.IsRequiresAdminUser), IsAlwaysRun: pointers.NewBoolPtr(oldStep.IsAlwaysRun), Inputs: inputs, Outputs: outputs, } return newStep, nil }
// FillMissingDefaults ... func (env *EnvironmentItemModel) FillMissingDefaults() error { options, err := env.GetOptions() if err != nil { return err } if options.Title == nil { options.Title = pointers.NewStringPtr("") } if options.Description == nil { options.Description = pointers.NewStringPtr("") } if options.Summary == nil { options.Summary = pointers.NewStringPtr("") } if options.IsRequired == nil { options.IsRequired = pointers.NewBoolPtr(DefaultIsRequired) } if options.IsExpand == nil { options.IsExpand = pointers.NewBoolPtr(DefaultIsExpand) } if options.IsDontChangeValue == nil { options.IsDontChangeValue = pointers.NewBoolPtr(DefaultIsDontChangeValue) } (*env)[OptionsKey] = options return nil }
// Test - Stepman audit step // Checks if step Source.Commit meets the git commit hash of realese version // 'auditStep(...)' calls 'cmdex.GitCloneTagOrBranchAndValidateCommitHash(...)', which method validates the commit hash func TestValidateStepCommitHash(t *testing.T) { // Slack step - valid hash stepSlack := models.StepModel{ Title: pointers.NewStringPtr("hash_test"), Summary: pointers.NewStringPtr("summary"), Website: pointers.NewStringPtr("website"), PublishedAt: pointers.NewTimePtr(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)), Source: &models.StepSourceModel{ Git: "https://github.com/bitrise-io/steps-slack-message.git", Commit: "756f39f76f94d525aaea2fc2d0c5a23799f8ec97", }, } if err := auditStepModelBeforeSharePullRequest(stepSlack, "slack", "2.1.0"); err != nil { t.Fatal("Step audit failed:", err) } // Slack step - invalid hash stepSlack.Source.Commit = "should fail commit" if err := auditStepModelBeforeSharePullRequest(stepSlack, "slack", "2.1.0"); err == nil { t.Fatal("Step audit should fail") } // Slack step - empty hash stepSlack.Source.Commit = "" if err := auditStepModelBeforeSharePullRequest(stepSlack, "slack", "2.1.0"); err == nil { t.Fatal("Step audit should fail") } }
func TestGetLatestStepVersion(t *testing.T) { defaultIsRequiresAdminUser := DefaultIsRequiresAdminUser step := StepModel{ Title: pointers.NewStringPtr("name 1"), Description: pointers.NewStringPtr("desc 1"), Website: pointers.NewStringPtr("web/1"), SourceCodeURL: pointers.NewStringPtr("fork/1"), Source: StepSourceModel{ Git: "https://git.url", }, HostOsTags: []string{"osx"}, ProjectTypeTags: []string{"ios"}, TypeTags: []string{"test"}, IsRequiresAdminUser: pointers.NewBoolPtr(defaultIsRequiresAdminUser), Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_1": "Value 1", }, envmanModels.EnvironmentItemModel{ "KEY_2": "Value 2", }, }, Outputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_3": "Value 3", }, }, } collection := StepCollectionModel{ FormatVersion: "1.0.0", GeneratedAtTimeStamp: 0, Steps: StepHash{ "step": StepGroupModel{ Versions: map[string]StepModel{ "1.0.0": step, "2.0.0": step, }, LatestVersionNumber: "2.0.0", }, }, SteplibSource: "source", DownloadLocations: []DownloadLocationModel{ DownloadLocationModel{ Type: "zip", Src: "amazon/", }, DownloadLocationModel{ Type: "git", Src: "step.git", }, }, } latest, err := collection.GetLatestStepVersion("step") require.Equal(t, nil, err) require.Equal(t, "2.0.0", latest) }
func TestValidate(t *testing.T) { step := StepModel{ Title: pointers.NewStringPtr("title"), Summary: pointers.NewStringPtr("summary"), Website: pointers.NewStringPtr("website"), PublishedAt: pointers.NewTimePtr(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)), Source: &StepSourceModel{ Git: "https://github.com/bitrise-io/bitrise.git", Commit: "1e1482141079fc12def64d88cb7825b8f1cb1dc3", }, } require.Equal(t, nil, step.Audit()) step.Title = nil require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'title' property") step.Title = new(string) *step.Title = "" require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'title' property") *step.Title = "title" step.PublishedAt = nil require.NotEqual(t, nil, step.Audit()) require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'PublishedAt' property") step.PublishedAt = new(time.Time) *step.PublishedAt = time.Time{} require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'PublishedAt' property") step.PublishedAt = pointers.NewTimePtr(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)) step.Website = nil require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'website' property") step.Website = new(string) *step.Website = "" require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'website' property") *step.Website = "website" step.Source.Git = "" require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'source.git' property") step.Source.Git = "git" step.Source.Git = "[email protected]:bitrise-io/bitrise.git" require.EqualError(t, step.Audit(), "Invalid step: step source should start with http:// or https://") step.Source.Git = "https://github.com/bitrise-io/bitrise" require.EqualError(t, step.Audit(), "Invalid step: step source should end with .git") step.Source.Git = "https://github.com/bitrise-io/bitrise.git" step.Source.Commit = "" require.EqualError(t, step.Audit(), "Invalid step: missing or empty required 'source.commit' property") step.Source.Commit = "1e1482141079fc12def64d88cb7825b8f1cb1dc3" step.Timeout = new(int) *step.Timeout = -1 require.EqualError(t, step.Audit(), "Invalid step: timeout less then 0") }
func TestGetStep(t *testing.T) { defaultIsRequiresAdminUser := DefaultIsRequiresAdminUser step := StepModel{ Title: pointers.NewStringPtr(title), Description: pointers.NewStringPtr(desc), Website: pointers.NewStringPtr(website), SourceCodeURL: pointers.NewStringPtr(fork), Source: StepSourceModel{ Git: git, }, HostOsTags: []string{"osx"}, ProjectTypeTags: []string{"ios"}, TypeTags: []string{"test"}, IsRequiresAdminUser: pointers.NewBoolPtr(defaultIsRequiresAdminUser), Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_1": "Value 1", }, envmanModels.EnvironmentItemModel{ "KEY_2": "Value 2", }, }, Outputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_3": "Value 3", }, }, } collection := StepCollectionModel{ FormatVersion: "1.0.0", GeneratedAtTimeStamp: 0, Steps: StepHash{ "step": StepGroupModel{ Versions: map[string]StepModel{ "1.0.0": step, }, }, }, SteplibSource: "source", DownloadLocations: []DownloadLocationModel{ DownloadLocationModel{ Type: "zip", Src: "amazon/", }, DownloadLocationModel{ Type: "git", Src: "step.git", }, }, } step, found := collection.GetStep("step", "1.0.0") if !found { t.Fatal("Step not found (step) (1.0.0)") } }
func (input InputModel) getOptions() envmanModels.EnvironmentItemOptionsModel { return envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(input.Title), Description: pointers.NewStringPtr(input.Description), ValueOptions: input.ValueOptions, IsRequired: pointers.NewBoolPtr(input.IsRequired), IsExpand: pointers.NewBoolPtr(input.IsExpand), IsDontChangeValue: pointers.NewBoolPtr(input.IsDontChangeValue), } }
// MergeEnvironmentWith ... func MergeEnvironmentWith(env *envmanModels.EnvironmentItemModel, otherEnv envmanModels.EnvironmentItemModel) error { // merge key-value key, _, err := env.GetKeyValuePair() if err != nil { return err } otherKey, otherValue, err := otherEnv.GetKeyValuePair() if err != nil { return err } if otherKey != key { return errors.New("Env keys are diferent") } (*env)[key] = otherValue //merge options options, err := env.GetOptions() if err != nil { return err } otherOptions, err := otherEnv.GetOptions() if err != nil { return err } if otherOptions.Title != nil { options.Title = pointers.NewStringPtr(*otherOptions.Title) } if otherOptions.Description != nil { options.Description = pointers.NewStringPtr(*otherOptions.Description) } if otherOptions.Summary != nil { options.Summary = pointers.NewStringPtr(*otherOptions.Summary) } if len(otherOptions.ValueOptions) > 0 { options.ValueOptions = otherOptions.ValueOptions } if otherOptions.IsRequired != nil { options.IsRequired = pointers.NewBoolPtr(*otherOptions.IsRequired) } if otherOptions.IsExpand != nil { options.IsExpand = pointers.NewBoolPtr(*otherOptions.IsExpand) } if otherOptions.IsDontChangeValue != nil { options.IsDontChangeValue = pointers.NewBoolPtr(*otherOptions.IsDontChangeValue) } if otherOptions.IsTemplate != nil { options.IsTemplate = pointers.NewBoolPtr(*otherOptions.IsTemplate) } (*env)[envmanModels.OptionsKey] = options return nil }
func TestValidate(t *testing.T) { step := StepModel{ Title: pointers.NewStringPtr("title"), Summary: pointers.NewStringPtr("summary"), Website: pointers.NewStringPtr("website"), PublishedAt: pointers.NewTimePtr(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC)), Source: StepSourceModel{ Git: "https://github.com/bitrise-io/bitrise.git", Commit: "1e1482141079fc12def64d88cb7825b8f1cb1dc3", }, } require.Equal(t, nil, step.Audit()) step.Title = nil require.NotEqual(t, nil, step.Audit()) step.Title = new(string) *step.Title = "" require.NotEqual(t, nil, step.Audit()) step.PublishedAt = nil require.NotEqual(t, nil, step.Audit()) step.PublishedAt = new(time.Time) *step.PublishedAt = time.Time{} require.NotEqual(t, nil, step.Audit()) step.Description = nil require.NotEqual(t, nil, step.Audit()) step.Description = new(string) *step.Description = "" require.NotEqual(t, nil, step.Audit()) step.Website = nil require.NotEqual(t, nil, step.Audit()) step.Website = new(string) *step.Website = "" require.NotEqual(t, nil, step.Audit()) step.Source.Git = "" require.NotEqual(t, nil, step.Audit()) step.Source.Git = "[email protected]:bitrise-io/bitrise.git" require.NotEqual(t, nil, step.Audit()) step.Source.Git = "https://github.com/bitrise-io/bitrise" require.NotEqual(t, nil, step.Audit()) step.Source.Commit = "" require.NotEqual(t, nil, step.Audit()) }
func TestMergeEnvironmentWith(t *testing.T) { diffEnv := envmanModels.EnvironmentItemModel{ "test_key": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), Description: pointers.NewStringPtr("test_description"), Summary: pointers.NewStringPtr("test_summary"), ValueOptions: []string{"test_valu_options1", "test_valu_options2"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(false), IsDontChangeValue: pointers.NewBoolPtr(true), IsTemplate: pointers.NewBoolPtr(true), }, } t.Log("Different keys") { env := envmanModels.EnvironmentItemModel{ "test_key1": "test_value", } require.Error(t, MergeEnvironmentWith(&env, diffEnv)) } t.Log("Normal merge") { env := envmanModels.EnvironmentItemModel{ "test_key": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ SkipIfEmpty: pointers.NewBoolPtr(true), Category: pointers.NewStringPtr("test"), }, } require.NoError(t, MergeEnvironmentWith(&env, diffEnv)) options, err := env.GetOptions() require.NoError(t, err) diffOptions, err := diffEnv.GetOptions() require.NoError(t, err) require.Equal(t, *diffOptions.Title, *options.Title) require.Equal(t, *diffOptions.Description, *options.Description) require.Equal(t, *diffOptions.Summary, *options.Summary) require.Equal(t, len(diffOptions.ValueOptions), len(options.ValueOptions)) require.Equal(t, *diffOptions.IsRequired, *options.IsRequired) require.Equal(t, *diffOptions.IsExpand, *options.IsExpand) require.Equal(t, *diffOptions.IsDontChangeValue, *options.IsDontChangeValue) require.Equal(t, *diffOptions.IsTemplate, *options.IsTemplate) require.Equal(t, true, *options.SkipIfEmpty) require.Equal(t, "test", *options.Category) } }
func Test_serialize_StepModel(t *testing.T) { t.Log("Empty") { step := StepModel{} // JSON { bytes, err := json.Marshal(step) require.NoError(t, err) require.Equal(t, `{}`, string(bytes)) } // YAML { bytes, err := yaml.Marshal(step) require.NoError(t, err) require.Equal(t, `{} `, string(bytes)) } } t.Log("Toolkit") { step := StepModel{ Title: pointers.NewStringPtr("Test Step"), Toolkit: &StepToolkitModel{ Go: &GoStepToolkitModel{ PackageName: "go/package", }, Bash: &BashStepToolkitModel{ EntryFile: "step.sh", }, }, } // JSON { bytes, err := json.Marshal(step) require.NoError(t, err) require.Equal(t, `{"title":"Test Step","toolkit":{"bash":{"entry_file":"step.sh"},"go":{"package_name":"go/package"}}}`, string(bytes)) } // YAML { bytes, err := yaml.Marshal(step) require.NoError(t, err) require.Equal(t, `title: Test Step toolkit: bash: entry_file: step.sh go: package_name: go/package `, string(bytes)) } } }
func TestFillMissingDefaults(t *testing.T) { title := "name 1" // "desc 1" := ""desc 1" 1" website := "web/1" git := "https://git.url" // fork := "fork/1" step := StepModel{ Title: pointers.NewStringPtr(title), Website: pointers.NewStringPtr(website), Source: &StepSourceModel{ Git: git, }, HostOsTags: []string{"osx"}, ProjectTypeTags: []string{"ios"}, TypeTags: []string{"test"}, } require.Equal(t, nil, step.FillMissingDefaults()) if step.Description == nil || *step.Description != "" { t.Fatal("Description missing") } if step.SourceCodeURL == nil || *step.SourceCodeURL != "" { t.Fatal("SourceCodeURL missing") } if step.SupportURL == nil || *step.SupportURL != "" { t.Fatal("SourceCodeURL missing") } if step.IsRequiresAdminUser == nil || *step.IsRequiresAdminUser != DefaultIsRequiresAdminUser { t.Fatal("IsRequiresAdminUser missing") } if step.IsAlwaysRun == nil || *step.IsAlwaysRun != DefaultIsAlwaysRun { t.Fatal("IsAlwaysRun missing") } if step.IsSkippable == nil || *step.IsSkippable != DefaultIsSkippable { t.Fatal("IsSkippable missing") } if step.RunIf == nil || *step.RunIf != "" { t.Fatal("RunIf missing") } if step.Timeout == nil || *step.Timeout != 0 { t.Fatal("Timeout missing") } }
func TestValidateStepInputOutputModel(t *testing.T) { // Filled env env := envmanModels.EnvironmentItemModel{ "test_key": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), Description: pointers.NewStringPtr("test_description"), Summary: pointers.NewStringPtr("test_summary"), ValueOptions: []string{"test_key2", "test_value2"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(false), IsDontChangeValue: pointers.NewBoolPtr(true), }, } step := StepModel{ Inputs: []envmanModels.EnvironmentItemModel{env}, } require.NoError(t, step.ValidateInputAndOutputEnvs(true)) // Empty key env = envmanModels.EnvironmentItemModel{ "": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), Description: pointers.NewStringPtr("test_description"), Summary: pointers.NewStringPtr("test_summary"), ValueOptions: []string{"test_key2", "test_value2"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(false), IsDontChangeValue: pointers.NewBoolPtr(true), }, } step = StepModel{ Inputs: []envmanModels.EnvironmentItemModel{env}, } require.Error(t, step.ValidateInputAndOutputEnvs(true)) // Title is empty env = envmanModels.EnvironmentItemModel{ "test_key": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Description: pointers.NewStringPtr("test_description"), ValueOptions: []string{"test_key2", "test_value2"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(false), IsDontChangeValue: pointers.NewBoolPtr(true), }, } step = StepModel{ Inputs: []envmanModels.EnvironmentItemModel{env}, } require.Error(t, step.ValidateInputAndOutputEnvs(true)) }
func TestRemoveDefaults(t *testing.T) { defaultIsRequired := models.DefaultIsRequired defaultIsExpand := models.DefaultIsExpand defaultIsDontChangeValue := models.DefaultIsDontChangeValue // Filled env env := models.EnvironmentItemModel{ testKey: testValue, models.OptionsKey: models.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), Description: pointers.NewStringPtr(testEmptyString), ValueOptions: []string{}, IsRequired: pointers.NewBoolPtr(defaultIsRequired), IsExpand: pointers.NewBoolPtr(defaultIsExpand), IsDontChangeValue: pointers.NewBoolPtr(defaultIsDontChangeValue), }, } err := removeDefaults(&env) if err != nil { t.Fatal(err) } opts, err := env.GetOptions() if err != nil { t.Fatal(err) } if opts.Title == nil { t.Fatal("Removed Title") } if opts.Description != nil { t.Fatal("Failed to remove default Description") } if opts.IsRequired != nil { t.Fatal("Failed to remove default IsRequired") } if opts.IsExpand != nil { t.Fatal("Failed to remove default IsExpand") } if opts.IsDontChangeValue != nil { t.Fatal("Failed to remove default IsDontChangeValue") } }
func TestValidateStepInputOutputModel(t *testing.T) { // Filled env env := envmanModels.EnvironmentItemModel{ testKey: testValue, envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), Description: pointers.NewStringPtr(testDescription), Summary: pointers.NewStringPtr(testSummary), ValueOptions: testValueOptions, IsRequired: pointers.NewBoolPtr(testTrue), IsExpand: pointers.NewBoolPtr(testFalse), IsDontChangeValue: pointers.NewBoolPtr(testTrue), }, } err := ValidateStepInputOutputModel(env, true) if err != nil { t.Fatal(err) } // Empty key env = envmanModels.EnvironmentItemModel{ "": testValue, envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), Description: pointers.NewStringPtr(testDescription), Summary: pointers.NewStringPtr(testSummary), ValueOptions: testValueOptions, IsRequired: pointers.NewBoolPtr(testTrue), IsExpand: pointers.NewBoolPtr(testFalse), IsDontChangeValue: pointers.NewBoolPtr(testTrue), }, } err = ValidateStepInputOutputModel(env, true) if err == nil { t.Fatal("Empty key, should fail") } // Title is empty env = envmanModels.EnvironmentItemModel{ testKey: testValue, envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Description: pointers.NewStringPtr(testDescription), ValueOptions: testValueOptions, IsRequired: pointers.NewBoolPtr(testTrue), IsExpand: pointers.NewBoolPtr(testFalse), IsDontChangeValue: pointers.NewBoolPtr(testTrue), }, } err = ValidateStepInputOutputModel(env, true) if err == nil { t.Fatal("Empty Title, should fail") } }
func TestRemoveDefaults(t *testing.T) { // Filled env env := models.EnvironmentItemModel{ "test_key": "test_value", models.OptionsKey: models.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), IsTemplate: pointers.NewBoolPtr(!models.DefaultIsTemplate), Description: pointers.NewStringPtr(""), Summary: pointers.NewStringPtr(""), ValueOptions: []string{}, IsRequired: pointers.NewBoolPtr(models.DefaultIsRequired), IsDontChangeValue: pointers.NewBoolPtr(models.DefaultIsDontChangeValue), IsExpand: pointers.NewBoolPtr(models.DefaultIsExpand), SkipIfEmpty: pointers.NewBoolPtr(models.DefaultSkipIfEmpty), }, } require.Equal(t, nil, removeDefaults(&env)) opts, err := env.GetOptions() require.Equal(t, nil, err) require.NotEqual(t, (*string)(nil), opts.Title) require.Equal(t, "test_title", *opts.Title) require.NotEqual(t, (*bool)(nil), opts.IsTemplate) require.Equal(t, !models.DefaultIsTemplate, *opts.IsTemplate) require.Equal(t, (*string)(nil), opts.Description) require.Equal(t, (*string)(nil), opts.Summary) require.Equal(t, 0, len(opts.ValueOptions)) require.Equal(t, (*bool)(nil), opts.IsRequired) require.Equal(t, (*bool)(nil), opts.IsDontChangeValue) require.Equal(t, (*bool)(nil), opts.IsExpand) require.Equal(t, (*bool)(nil), opts.SkipIfEmpty) }
func TestValidate(t *testing.T) { // No key-value env := EnvironmentItemModel{ OptionsKey: EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), Description: pointers.NewStringPtr(testDescription), Summary: pointers.NewStringPtr(testSummary), ValueOptions: testValueOptions, IsRequired: pointers.NewBoolPtr(testTrue), IsExpand: pointers.NewBoolPtr(testTrue), IsDontChangeValue: pointers.NewBoolPtr(testFalse), }, } err := env.Validate() if err == nil { t.Fatal("Should be invalid env, no key-value") } // Empty key env = EnvironmentItemModel{ "": testValue, } err = env.Validate() if err == nil { t.Fatal("Should be invalid env, no empty key") } // Valid env env = EnvironmentItemModel{ testKey: testValue, } err = env.Validate() if err != nil { t.Fatal(err) } }
// CertificateStep ... // // Cerificate step separated in new StepLib // so need to insert befor new Xcode steps func CertificateStep() ([]bitriseModels.StepListItemModel, error) { certificateStep, version, err := GetStepFromNewSteplib(CertificateStepID, BitriseVerifiedStepLibGitURI) if err != nil { return []bitriseModels.StepListItemModel{}, err } certificateStep.RunIf = pointers.NewStringPtr(".IsCI") stepIDDataString := CertificateStepID + "@" + version return []bitriseModels.StepListItemModel{ bitriseModels.StepListItemModel{ stepIDDataString: certificateStep, }, }, nil }
// FillMissingDefaults ... func (step *StepModel) FillMissingDefaults() error { if step.Title == nil { step.Title = pointers.NewStringPtr("") } if step.Description == nil { step.Description = pointers.NewStringPtr("") } if step.Summary == nil { step.Summary = pointers.NewStringPtr("") } if step.Website == nil { step.Website = pointers.NewStringPtr("") } if step.SourceCodeURL == nil { step.SourceCodeURL = pointers.NewStringPtr("") } if step.SupportURL == nil { step.SupportURL = pointers.NewStringPtr("") } if step.IsRequiresAdminUser == nil { step.IsRequiresAdminUser = pointers.NewBoolPtr(DefaultIsRequiresAdminUser) } if step.IsAlwaysRun == nil { step.IsAlwaysRun = pointers.NewBoolPtr(DefaultIsAlwaysRun) } if step.IsSkippable == nil { step.IsSkippable = pointers.NewBoolPtr(DefaultIsSkippable) } if step.RunIf == nil { step.RunIf = pointers.NewStringPtr("") } if step.Timeout == nil { step.Timeout = pointers.NewIntPtr(DefaultTimeout) } for _, input := range step.Inputs { err := input.FillMissingDefaults() if err != nil { return err } } for _, output := range step.Outputs { err := output.FillMissingDefaults() if err != nil { return err } } return nil }
func TestAddStepVersionToStepGroup(t *testing.T) { step := models.StepModel{ Title: pointers.NewStringPtr("name 1"), } group := models.StepGroupModel{ Versions: map[string]models.StepModel{ "1.0.0": step, "2.0.0": step, }, LatestVersionNumber: "2.0.0", } group, err := addStepVersionToStepGroup(step, "2.1.0", group) require.Equal(t, nil, err) require.Equal(t, 3, len(group.Versions)) require.Equal(t, "2.1.0", group.LatestVersionNumber) }
func TestGetOptions(t *testing.T) { // Filled env env := EnvironmentItemModel{ testKey: testValue, OptionsKey: EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), IsExpand: pointers.NewBoolPtr(testFalse), }, } opts, err := env.GetOptions() if err != nil { t.Fatal(err) } if opts.Title == nil || *opts.Title != testTitle { t.Fatal("Title is nil, or not correct") } if opts.IsExpand == nil || *opts.IsExpand != testFalse { t.Fatal("IsExpand is nil, or not correct") } // Missing opts env = EnvironmentItemModel{ testKey: testValue, } _, err = env.GetOptions() if err != nil { t.Fatal(err) } // Wrong opts env = EnvironmentItemModel{ testKey: testValue, OptionsKey: map[interface{}]interface{}{ "title": testTitle, "test": testDescription, }, } _, err = env.GetOptions() if err == nil { t.Fatal(err) } }
// ConvertStep ... // // Converted step should: // * keep original Title // * keep original IsAlwaysRun // // newStepID: the id of the new step in new StepLib // diffStep: readed from workflow to convert // func ConvertStep(diffStep stepmanModels.StepModel, newStepID string, inputConversionMap map[string]string) (stepmanModels.StepModel, string, error) { originalStep, version, err := GetStepFromNewSteplib(newStepID, BitriseVerifiedStepLibGitURI) if err != nil { return stepmanModels.StepModel{}, "", err } if diffStep.Title != nil { originalStep.Title = pointers.NewStringPtr(*diffStep.Title) } if diffStep.IsAlwaysRun != nil { originalStep.IsAlwaysRun = pointers.NewBoolPtr(*diffStep.IsAlwaysRun) } // Merge new StepLib version inputs, with old workflow defined mergedInputs, err := convertStepsInputs(originalStep.Inputs, diffStep.Inputs, inputConversionMap) if err != nil { return stepmanModels.StepModel{}, "", err } originalStep.Inputs = mergedInputs return originalStep, version, nil }
func TestGetOptions(t *testing.T) { // Filled env env := EnvironmentItemModel{ "test_key": "test_value", OptionsKey: EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("test_title"), IsExpand: pointers.NewBoolPtr(false), }, } opts, err := env.GetOptions() require.Equal(t, nil, err) require.NotEqual(t, nil, opts.Title) require.Equal(t, "test_title", *opts.Title) require.NotEqual(t, nil, opts.IsExpand) require.Equal(t, false, *opts.IsExpand) // Missing opts env = EnvironmentItemModel{ "test_key": "test_value", } _, err = env.GetOptions() require.Equal(t, nil, err) // Wrong opts env = EnvironmentItemModel{ "test_key": "test_value", OptionsKey: map[interface{}]interface{}{ "title": "test_title", "test": "test_description", }, } _, err = env.GetOptions() require.NotEqual(t, nil, err) }
// ParseFromInterfaceMap ... func (envSerModel *EnvironmentItemOptionsModel) ParseFromInterfaceMap(input map[string]interface{}) error { for keyStr, value := range input { log.Debugf(" ** processing (key:%#v) (value:%#v) (envSerModel:%#v)", keyStr, value, envSerModel) switch keyStr { case "title": castedValue, ok := value.(string) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.Title = pointers.NewStringPtr(castedValue) case "description": castedValue, ok := value.(string) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.Description = pointers.NewStringPtr(castedValue) case "summary": castedValue, ok := value.(string) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.Summary = pointers.NewStringPtr(castedValue) case "value_options": castedValue, ok := value.([]string) if !ok { // try with []interface{} instead and cast the // items to string castedValue = []string{} interfArr, ok := value.([]interface{}) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } for _, interfItm := range interfArr { castedItm, ok := interfItm.(string) if !ok { return fmt.Errorf("Invalid value in value_options (%#v), not a string: %#v", interfArr, interfItm) } castedValue = append(castedValue, castedItm) } } envSerModel.ValueOptions = castedValue case "is_required": castedValue, ok := value.(bool) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.IsRequired = pointers.NewBoolPtr(castedValue) case "is_expand": castedValue, ok := value.(bool) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.IsExpand = pointers.NewBoolPtr(castedValue) case "is_dont_change_value": castedValue, ok := value.(bool) if !ok { return fmt.Errorf("Invalid value type (key:%s): %#v", keyStr, value) } envSerModel.IsDontChangeValue = pointers.NewBoolPtr(castedValue) default: return fmt.Errorf("Not supported key found in options: %#v", keyStr) } } return nil }
func TestMergeStepWith(t *testing.T) { desc := "desc 1" summ := "sum 1" website := "web/1" fork := "fork/1" published := time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC) stepData := stepmanModels.StepModel{ Description: pointers.NewStringPtr(desc), Summary: pointers.NewStringPtr(summ), Website: pointers.NewStringPtr(website), SourceCodeURL: pointers.NewStringPtr(fork), PublishedAt: pointers.NewTimePtr(published), HostOsTags: []string{"osx"}, ProjectTypeTags: []string{"ios"}, TypeTags: []string{"test"}, IsRequiresAdminUser: pointers.NewBoolPtr(true), Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_1": "Value 1", }, envmanModels.EnvironmentItemModel{ "KEY_2": "Value 2", }, }, Outputs: []envmanModels.EnvironmentItemModel{}, } diffTitle := "name 2" newSuppURL := "supp" runIfStr := "" stepDiffToMerge := stepmanModels.StepModel{ Title: pointers.NewStringPtr(diffTitle), HostOsTags: []string{"linux"}, Source: &stepmanModels.StepSourceModel{ Git: "https://git.url", }, Dependencies: []stepmanModels.DependencyModel{ stepmanModels.DependencyModel{ Manager: "brew", Name: "test", }, }, SupportURL: pointers.NewStringPtr(newSuppURL), RunIf: pointers.NewStringPtr(runIfStr), Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_2": "Value 2 CHANGED", }, }, Timeout: pointers.NewIntPtr(1), Toolkit: &stepmanModels.StepToolkitModel{ Go: &stepmanModels.GoStepToolkitModel{ PackageName: "test", }, }, } mergedStepData, err := MergeStepWith(stepData, stepDiffToMerge) require.NoError(t, err) require.Equal(t, "name 2", *mergedStepData.Title) require.Equal(t, "desc 1", *mergedStepData.Description) require.Equal(t, "sum 1", *mergedStepData.Summary) require.Equal(t, "web/1", *mergedStepData.Website) require.Equal(t, "fork/1", *mergedStepData.SourceCodeURL) require.Equal(t, true, (*mergedStepData.PublishedAt).Equal(time.Date(2012, time.January, 1, 0, 0, 0, 0, time.UTC))) require.Equal(t, "linux", mergedStepData.HostOsTags[0]) require.Equal(t, "", *mergedStepData.RunIf) require.Equal(t, 1, len(mergedStepData.Dependencies)) require.Equal(t, "test", mergedStepData.Toolkit.Go.PackageName) require.Equal(t, 1, *mergedStepData.Timeout) dep := mergedStepData.Dependencies[0] require.Equal(t, "brew", dep.Manager) require.Equal(t, "test", dep.Name) // inputs input0 := mergedStepData.Inputs[0] key0, value0, err := input0.GetKeyValuePair() require.NoError(t, err) require.Equal(t, "KEY_1", key0) require.Equal(t, "Value 1", value0) input1 := mergedStepData.Inputs[1] key1, value1, err := input1.GetKeyValuePair() require.NoError(t, err) require.Equal(t, "KEY_2", key1) require.Equal(t, "Value 2 CHANGED", value1) }
func TestRemoveEnvironmentRedundantFields(t *testing.T) { t.Log("Trivial remove - all fields should be default value") { env := envmanModels.EnvironmentItemModel{ "TEST_KEY": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(""), Description: pointers.NewStringPtr(""), Summary: pointers.NewStringPtr(""), ValueOptions: []string{}, IsRequired: pointers.NewBoolPtr(envmanModels.DefaultIsRequired), IsExpand: pointers.NewBoolPtr(envmanModels.DefaultIsExpand), IsDontChangeValue: pointers.NewBoolPtr(envmanModels.DefaultIsDontChangeValue), IsTemplate: pointers.NewBoolPtr(envmanModels.DefaultIsTemplate), }, } require.NoError(t, removeEnvironmentRedundantFields(&env)) options, err := env.GetOptions() require.NoError(t, err) require.Equal(t, (*string)(nil), options.Title) require.Equal(t, (*string)(nil), options.Description) require.Equal(t, (*string)(nil), options.Summary) require.Equal(t, 0, len(options.ValueOptions)) require.Equal(t, (*bool)(nil), options.IsRequired) require.Equal(t, (*bool)(nil), options.IsExpand) require.Equal(t, (*bool)(nil), options.IsDontChangeValue) require.Equal(t, (*bool)(nil), options.IsTemplate) } t.Log("Trivial don't remove - no fields should be default value") { env := envmanModels.EnvironmentItemModel{ "TEST_KEY": "test_value", envmanModels.OptionsKey: envmanModels.EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr("t"), Description: pointers.NewStringPtr("d"), Summary: pointers.NewStringPtr("s"), ValueOptions: []string{"i"}, IsRequired: pointers.NewBoolPtr(true), IsExpand: pointers.NewBoolPtr(false), IsDontChangeValue: pointers.NewBoolPtr(true), IsTemplate: pointers.NewBoolPtr(true), }, } require.NoError(t, removeEnvironmentRedundantFields(&env)) options, err := env.GetOptions() require.NoError(t, err) require.Equal(t, "t", *options.Title) require.Equal(t, "d", *options.Description) require.Equal(t, "s", *options.Summary) require.Equal(t, "i", options.ValueOptions[0]) require.Equal(t, true, *options.IsRequired) require.Equal(t, false, *options.IsExpand) require.Equal(t, true, *options.IsDontChangeValue) require.Equal(t, true, *options.IsTemplate) } t.Log("No options - opts field shouldn't exist") { env := envmanModels.EnvironmentItemModel{ "TEST_KEY": "test_value", } require.NoError(t, removeEnvironmentRedundantFields(&env)) _, ok := env[envmanModels.OptionsKey] require.Equal(t, false, ok) } }
func TestGetDownloadLocations(t *testing.T) { defaultIsRequiresAdminUser := DefaultIsRequiresAdminUser // Zip & git download locations step := StepModel{ Title: pointers.NewStringPtr("name 1"), Description: pointers.NewStringPtr("desc 1"), Website: pointers.NewStringPtr("web/1"), SourceCodeURL: pointers.NewStringPtr("fork/1"), Source: StepSourceModel{ Git: "https://git.url", }, HostOsTags: []string{"osx"}, ProjectTypeTags: []string{"ios"}, TypeTags: []string{"test"}, IsRequiresAdminUser: pointers.NewBoolPtr(defaultIsRequiresAdminUser), Inputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_1": "Value 1", }, envmanModels.EnvironmentItemModel{ "KEY_2": "Value 2", }, }, Outputs: []envmanModels.EnvironmentItemModel{ envmanModels.EnvironmentItemModel{ "KEY_3": "Value 3", }, }, } collection := StepCollectionModel{ FormatVersion: "1.0.0", GeneratedAtTimeStamp: 0, Steps: StepHash{ "step": StepGroupModel{ Versions: map[string]StepModel{ "1.0.0": step, }, }, }, SteplibSource: "source", DownloadLocations: []DownloadLocationModel{ DownloadLocationModel{ Type: "zip", Src: "amazon/", }, DownloadLocationModel{ Type: "git", Src: "step.git", }, }, } locations, err := collection.GetDownloadLocations("step", "1.0.0") require.Equal(t, nil, err) zipFound := false gitFount := false zipIdx := -1 gitIdx := -1 for idx, location := range locations { if location.Type == "zip" { if location.Src != "amazon/step/1.0.0/step.zip" { t.Fatalf("Incorrect zip location (%s)", location.Src) } zipFound = true zipIdx = idx } else if location.Type == "git" { if location.Src != "https://git.url" { t.Fatalf("Incorrect git location (%s)", location.Src) } gitFount = true gitIdx = idx } } require.Equal(t, true, zipFound) require.Equal(t, true, gitFount) if gitIdx < zipIdx { t.Fatal("Incorrect download locations order") } }
func TestFillMissingDefaults(t *testing.T) { // Empty env env := EnvironmentItemModel{ testKey: testValue, } err := env.FillMissingDefaults() if err != nil { t.Fatal(err) } opts, err := env.GetOptions() if err != nil { t.Fatal(err) } // required // if opts.Title == nil || *opts.Title != "" { // t.Fatal("Failed to fill Title default value") // } if opts.Description == nil || *opts.Description != "" { t.Fatal("Failed to fill Description default value") } if opts.Summary == nil || *opts.Summary != "" { t.Fatal("Failed to fill Summary default value") } if opts.IsRequired == nil || *opts.IsRequired != DefaultIsRequired { t.Fatal("Failed to fill IsRequired default value") } if opts.IsExpand == nil || *opts.IsExpand != DefaultIsExpand { t.Fatal("Failed to fill IsExpand default value") } if opts.IsDontChangeValue == nil || *opts.IsDontChangeValue != DefaultIsDontChangeValue { t.Fatal("Failed to fill IsDontChangeValue default value") } // Filled env env = EnvironmentItemModel{ testKey: testValue, OptionsKey: EnvironmentItemOptionsModel{ Title: pointers.NewStringPtr(testTitle), Description: pointers.NewStringPtr(testDescription), Summary: pointers.NewStringPtr(testSummary), ValueOptions: testValueOptions, IsRequired: pointers.NewBoolPtr(testTrue), IsExpand: pointers.NewBoolPtr(testTrue), IsDontChangeValue: pointers.NewBoolPtr(testFalse), }, } err = env.FillMissingDefaults() if err != nil { t.Fatal(err) } opts, err = env.GetOptions() if err != nil { t.Fatal(err) } if opts.Title == nil || *opts.Title != testTitle { t.Fatal("Title is nil, or not correct") } if opts.Description == nil || *opts.Description != testDescription { t.Fatal("Description is nil, or not correct") } if opts.Summary == nil || *opts.Summary != testSummary { t.Fatal("Summary is nil, or not correct") } if len(opts.ValueOptions) != len(testValueOptions) { t.Fatal("ValueOptions element num is not correct") } if opts.IsRequired == nil || *opts.IsRequired != testTrue { t.Fatal("IsRequired is nil, or not correct") } if opts.IsExpand == nil || *opts.IsExpand != testTrue { t.Fatal("IsExpand is nil, or not correct") } if opts.IsDontChangeValue == nil || *opts.IsDontChangeValue != testFalse { t.Fatal("IsDontChangeValue is nil, or not correct") } }
// MergeStepWith ... func MergeStepWith(step, otherStep stepmanModels.StepModel) (stepmanModels.StepModel, error) { if otherStep.Title != nil { step.Title = pointers.NewStringPtr(*otherStep.Title) } if otherStep.Description != nil { step.Description = pointers.NewStringPtr(*otherStep.Description) } if otherStep.Summary != nil { step.Summary = pointers.NewStringPtr(*otherStep.Summary) } if otherStep.Website != nil { step.Website = pointers.NewStringPtr(*otherStep.Website) } if otherStep.SourceCodeURL != nil { step.SourceCodeURL = pointers.NewStringPtr(*otherStep.SourceCodeURL) } if otherStep.SupportURL != nil { step.SupportURL = pointers.NewStringPtr(*otherStep.SupportURL) } if otherStep.PublishedAt != nil { step.PublishedAt = pointers.NewTimePtr(*otherStep.PublishedAt) } if otherStep.Source.Git != "" { step.Source.Git = otherStep.Source.Git } if otherStep.Source.Commit != "" { step.Source.Commit = otherStep.Source.Commit } if len(otherStep.Dependencies) > 0 { step.Dependencies = otherStep.Dependencies } if len(otherStep.Deps.Brew) > 0 || len(otherStep.Deps.AptGet) > 0 || len(otherStep.Deps.CheckOnly) > 0 { step.Deps = otherStep.Deps } if len(otherStep.HostOsTags) > 0 { step.HostOsTags = otherStep.HostOsTags } if len(otherStep.ProjectTypeTags) > 0 { step.ProjectTypeTags = otherStep.ProjectTypeTags } if len(otherStep.TypeTags) > 0 { step.TypeTags = otherStep.TypeTags } if otherStep.IsRequiresAdminUser != nil { step.IsRequiresAdminUser = pointers.NewBoolPtr(*otherStep.IsRequiresAdminUser) } if otherStep.IsAlwaysRun != nil { step.IsAlwaysRun = pointers.NewBoolPtr(*otherStep.IsAlwaysRun) } if otherStep.IsSkippable != nil { step.IsSkippable = pointers.NewBoolPtr(*otherStep.IsSkippable) } if otherStep.RunIf != nil { step.RunIf = pointers.NewStringPtr(*otherStep.RunIf) } for _, input := range step.Inputs { key, _, err := input.GetKeyValuePair() if err != nil { return stepmanModels.StepModel{}, err } otherInput, found := getInputByKey(otherStep, key) if found { err := MergeEnvironmentWith(&input, otherInput) if err != nil { return stepmanModels.StepModel{}, err } } } for _, output := range step.Outputs { key, _, err := output.GetKeyValuePair() if err != nil { return stepmanModels.StepModel{}, err } otherOutput, found := getOutputByKey(otherStep, key) if found { err := MergeEnvironmentWith(&output, otherOutput) if err != nil { return stepmanModels.StepModel{}, err } } } return step, nil }