github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/webhook/converter_test.go (about)

     1  package webhook_test
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/kyma-incubator/compass/components/director/pkg/auth"
    10  
    11  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    12  
    13  	"github.com/pkg/errors"
    14  	"github.com/stretchr/testify/require"
    15  
    16  	"github.com/kyma-incubator/compass/components/director/internal/domain/webhook"
    17  	"github.com/kyma-incubator/compass/components/director/internal/domain/webhook/automock"
    18  	"github.com/kyma-incubator/compass/components/director/internal/model"
    19  	"github.com/kyma-incubator/compass/components/director/pkg/graphql"
    20  	"github.com/stretchr/testify/assert"
    21  )
    22  
    23  var (
    24  	givenAppID         = "givenApplicationID"
    25  	modelWebhookMode   = model.WebhookModeSync
    26  	graphqlWebhookMode = graphql.WebhookModeSync
    27  )
    28  
    29  func TestConverter_ToGraphQL(t *testing.T) {
    30  	// GIVEN
    31  	testCases := []struct {
    32  		Name     string
    33  		Input    *model.Webhook
    34  		Expected *graphql.Webhook
    35  	}{
    36  		{
    37  			Name:     "All properties given",
    38  			Input:    fixApplicationModelWebhook("1", "foo", "", "bar", time.Time{}),
    39  			Expected: fixApplicationGQLWebhook("1", "foo", "bar"),
    40  		},
    41  		{
    42  			Name:     "Empty",
    43  			Input:    &model.Webhook{},
    44  			Expected: &graphql.Webhook{},
    45  		},
    46  		{
    47  			Name:     "Nil",
    48  			Input:    nil,
    49  			Expected: nil,
    50  		},
    51  	}
    52  
    53  	for _, testCase := range testCases {
    54  		t.Run(testCase.Name, func(t *testing.T) {
    55  			authConv := &automock.AuthConverter{}
    56  			if testCase.Input != nil {
    57  				authConv.On("ToGraphQL", testCase.Input.Auth).Return(testCase.Expected.Auth, nil)
    58  			}
    59  			converter := webhook.NewConverter(authConv)
    60  
    61  			// WHEN
    62  			res, err := converter.ToGraphQL(testCase.Input)
    63  
    64  			// THEN
    65  			assert.NoError(t, err)
    66  			assert.Equal(t, testCase.Expected, res)
    67  			authConv.AssertExpectations(t)
    68  		})
    69  	}
    70  }
    71  
    72  func TestConverter_ToModel(t *testing.T) {
    73  	id := "id"
    74  	objectID := "objectID"
    75  	url := "url"
    76  
    77  	appInput := fixApplicationGQLWebhook(id, objectID, url)
    78  	expectedApp := fixApplicationModelWebhook(id, objectID, "", url, time.Time{})
    79  	var err error
    80  	expectedApp.Auth, err = auth.ToModel(appInput.Auth)
    81  	assert.NoError(t, err)
    82  
    83  	runtimeInput := fixRuntimeGQLWebhook(id, objectID, url)
    84  	expectedRuntime := fixRuntimeModelWebhook(id, objectID, url)
    85  	expectedRuntime.Auth, err = auth.ToModel(runtimeInput.Auth)
    86  	assert.NoError(t, err)
    87  
    88  	appTmplInput := fixApplicationTemplateGQLWebhook(id, objectID, url)
    89  	expectedAppTmpl := fixApplicationTemplateModelWebhook(id, objectID, url)
    90  	expectedAppTmpl.Auth, err = auth.ToModel(appTmplInput.Auth)
    91  	assert.NoError(t, err)
    92  
    93  	formationTmplInput := fixFormationTemplateGQLWebhook(id, objectID, url)
    94  	expectedFormationTmpl := fixFormationTemplateModelWebhook(id, objectID, url)
    95  	expectedFormationTmpl.Auth, err = auth.ToModel(formationTmplInput.Auth)
    96  	assert.NoError(t, err)
    97  
    98  	intSysInput := fixIntegrationSystemGQLWebhook(id, objectID, url)
    99  	expectedIntSys := fixIntegrationSystemModelWebhook(id, objectID, url)
   100  	expectedIntSys.Auth, err = auth.ToModel(intSysInput.Auth)
   101  	assert.NoError(t, err)
   102  
   103  	unknownInput := fixGenericGQLWebhook(id, url)
   104  	expectedUnknown := fixGenericModelWebhook(id, "", url)
   105  	expectedUnknown.Auth, err = auth.ToModel(unknownInput.Auth)
   106  	assert.NoError(t, err)
   107  
   108  	testCases := []struct {
   109  		Name     string
   110  		Input    *graphql.Webhook
   111  		Expected *model.Webhook
   112  	}{
   113  		{
   114  			Name:     "Success when object type is application",
   115  			Input:    appInput,
   116  			Expected: expectedApp,
   117  		},
   118  		{
   119  			Name:     "Success when object type is runtime",
   120  			Input:    runtimeInput,
   121  			Expected: expectedRuntime,
   122  		},
   123  		{
   124  			Name:     "Success when object type is application template",
   125  			Input:    appTmplInput,
   126  			Expected: expectedAppTmpl,
   127  		},
   128  		{
   129  			Name:     "Success when object type is formation template",
   130  			Input:    formationTmplInput,
   131  			Expected: expectedFormationTmpl,
   132  		},
   133  		{
   134  			Name:     "Success when object type is integration system",
   135  			Input:    intSysInput,
   136  			Expected: expectedIntSys,
   137  		},
   138  		{
   139  			Name:     "Success when object type is unknown",
   140  			Input:    unknownInput,
   141  			Expected: expectedUnknown,
   142  		},
   143  		{
   144  			Name: "Success when input is nil",
   145  		},
   146  	}
   147  
   148  	for _, testCase := range testCases {
   149  		t.Run(testCase.Name, func(t *testing.T) {
   150  			converter := webhook.NewConverter(&automock.AuthConverter{})
   151  
   152  			// WHEN
   153  			res, err := converter.ToModel(testCase.Input)
   154  
   155  			// THEN
   156  			assert.NoError(t, err)
   157  			assert.Equal(t, testCase.Expected, res)
   158  		})
   159  	}
   160  }
   161  
   162  func TestConverter_MultipleToGraphQL(t *testing.T) {
   163  	// GIVEN
   164  	input := []*model.Webhook{
   165  		fixApplicationModelWebhook("1", "foo", "", "baz", time.Time{}),
   166  		fixApplicationModelWebhook("2", "bar", "", "bez", time.Time{}),
   167  		{},
   168  		nil,
   169  	}
   170  	expected := []*graphql.Webhook{
   171  		fixApplicationGQLWebhook("1", "foo", "baz"),
   172  		fixApplicationGQLWebhook("2", "bar", "bez"),
   173  		{},
   174  	}
   175  	authConv := &automock.AuthConverter{}
   176  	authConv.On("ToGraphQL", input[0].Auth).Return(expected[0].Auth, nil)
   177  	authConv.On("ToGraphQL", (*model.Auth)(nil)).Return(nil, nil)
   178  	converter := webhook.NewConverter(authConv)
   179  
   180  	// WHEN
   181  	res, err := converter.MultipleToGraphQL(input)
   182  
   183  	// THEN
   184  	assert.NoError(t, err)
   185  	assert.Equal(t, expected, res)
   186  	authConv.AssertExpectations(t)
   187  }
   188  
   189  func TestConverter_InputFromGraphQL(t *testing.T) {
   190  	// GIVEN
   191  	testCases := []struct {
   192  		Name     string
   193  		Input    *graphql.WebhookInput
   194  		Expected *model.WebhookInput
   195  		Error    error
   196  	}{
   197  		{
   198  			Name:     "All properties given",
   199  			Input:    fixGQLWebhookInput("https://test-domain.com"),
   200  			Expected: fixModelWebhookInput("https://test-domain.com"),
   201  			Error:    nil,
   202  		},
   203  		{
   204  			Name:     "Empty",
   205  			Input:    &graphql.WebhookInput{},
   206  			Expected: &model.WebhookInput{},
   207  			Error:    nil,
   208  		},
   209  		{
   210  			Name:     "Nil",
   211  			Input:    nil,
   212  			Expected: nil,
   213  			Error:    nil,
   214  		},
   215  	}
   216  
   217  	for _, testCase := range testCases {
   218  		t.Run(testCase.Name, func(t *testing.T) {
   219  			authConv := &automock.AuthConverter{}
   220  			if testCase.Input != nil && testCase.Error == nil {
   221  				authConv.On("InputFromGraphQL", testCase.Input.Auth).Return(testCase.Expected.Auth, nil)
   222  			}
   223  			converter := webhook.NewConverter(authConv)
   224  
   225  			// WHEN
   226  			res, err := converter.InputFromGraphQL(testCase.Input)
   227  
   228  			// then
   229  			if testCase.Error == nil {
   230  				assert.NoError(t, err)
   231  				assert.Equal(t, testCase.Expected, res)
   232  			} else {
   233  				assert.Error(t, err, testCase.Error)
   234  			}
   235  			authConv.AssertExpectations(t)
   236  		})
   237  	}
   238  }
   239  
   240  func TestConverter_MultipleInputFromGraphQL(t *testing.T) {
   241  	// GIVEN
   242  	input := []*graphql.WebhookInput{
   243  		fixGQLWebhookInput("https://test-domain.com"),
   244  		fixGQLWebhookInput("https://test-domain.com"),
   245  		nil,
   246  	}
   247  	expected := []*model.WebhookInput{
   248  		fixModelWebhookInput("https://test-domain.com"),
   249  		fixModelWebhookInput("https://test-domain.com"),
   250  	}
   251  	authConv := &automock.AuthConverter{}
   252  	authConv.On("InputFromGraphQL", input[0].Auth).Return(expected[0].Auth, nil)
   253  	converter := webhook.NewConverter(authConv)
   254  
   255  	// WHEN
   256  	res, err := converter.MultipleInputFromGraphQL(input)
   257  
   258  	// then
   259  	assert.NoError(t, err)
   260  	assert.Equal(t, expected, res)
   261  	authConv.AssertExpectations(t)
   262  }
   263  
   264  func TestConverter_ToEntity(t *testing.T) {
   265  	sut := webhook.NewConverter(nil)
   266  
   267  	b, err := json.Marshal(fixBasicAuth())
   268  	require.NoError(t, err)
   269  	expectedBasicAuthAsString := string(b)
   270  
   271  	testCases := map[string]struct {
   272  		in       *model.Webhook
   273  		expected *webhook.Entity
   274  	}{
   275  		"success when Auth not provided": {
   276  			in: &model.Webhook{
   277  				ID:             "givenID",
   278  				ObjectID:       givenAppID,
   279  				ObjectType:     model.ApplicationWebhookReference,
   280  				URL:            stringPtr("https://test-domain.com"),
   281  				Type:           model.WebhookTypeConfigurationChanged,
   282  				Mode:           &modelWebhookMode,
   283  				URLTemplate:    &emptyTemplate,
   284  				InputTemplate:  &emptyTemplate,
   285  				HeaderTemplate: &emptyTemplate,
   286  				OutputTemplate: &emptyTemplate,
   287  			},
   288  			expected: &webhook.Entity{
   289  				ID:             "givenID",
   290  				ApplicationID:  repo.NewValidNullableString(givenAppID),
   291  				URL:            repo.NewValidNullableString("https://test-domain.com"),
   292  				Type:           "CONFIGURATION_CHANGED",
   293  				Auth:           sql.NullString{Valid: false},
   294  				Mode:           repo.NewValidNullableString("SYNC"),
   295  				URLTemplate:    repo.NewValidNullableString(emptyTemplate),
   296  				InputTemplate:  repo.NewValidNullableString(emptyTemplate),
   297  				HeaderTemplate: repo.NewValidNullableString(emptyTemplate),
   298  				OutputTemplate: repo.NewValidNullableString(emptyTemplate),
   299  			},
   300  		},
   301  		"success when Auth provided": {
   302  			in: &model.Webhook{
   303  				Auth: fixBasicAuth(),
   304  			},
   305  			expected: &webhook.Entity{
   306  				Auth: sql.NullString{Valid: true, String: expectedBasicAuthAsString},
   307  			},
   308  		},
   309  	}
   310  
   311  	for tn, tc := range testCases {
   312  		t.Run(tn, func(t *testing.T) {
   313  			// WHEN
   314  			actual, err := sut.ToEntity(tc.in)
   315  			// THEN
   316  			require.NoError(t, err)
   317  			assert.Equal(t, tc.expected, actual)
   318  		})
   319  	}
   320  }
   321  
   322  func TestConverter_FromEntity(t *testing.T) {
   323  	// GIVEN
   324  	sut := webhook.NewConverter(nil)
   325  	b, err := json.Marshal(fixBasicAuth())
   326  	require.NoError(t, err)
   327  
   328  	testCases := map[string]struct {
   329  		inEntity      *webhook.Entity
   330  		expectedModel *model.Webhook
   331  		expectedErr   error
   332  	}{
   333  		"success when Auth not provided": {
   334  			inEntity: &webhook.Entity{
   335  				ID:             "givenID",
   336  				Type:           "CONFIGURATION_CHANGED",
   337  				URL:            repo.NewValidNullableString("https://test-domain.com"),
   338  				ApplicationID:  repo.NewValidNullableString(givenAppID),
   339  				Mode:           repo.NewValidNullableString("SYNC"),
   340  				URLTemplate:    repo.NewValidNullableString(emptyTemplate),
   341  				InputTemplate:  repo.NewValidNullableString(emptyTemplate),
   342  				HeaderTemplate: repo.NewValidNullableString(emptyTemplate),
   343  				OutputTemplate: repo.NewValidNullableString(emptyTemplate),
   344  			},
   345  			expectedModel: &model.Webhook{
   346  				ID:             "givenID",
   347  				Type:           "CONFIGURATION_CHANGED",
   348  				URL:            stringPtr("https://test-domain.com"),
   349  				ObjectID:       givenAppID,
   350  				ObjectType:     model.ApplicationWebhookReference,
   351  				Auth:           nil,
   352  				Mode:           &modelWebhookMode,
   353  				URLTemplate:    &emptyTemplate,
   354  				InputTemplate:  &emptyTemplate,
   355  				HeaderTemplate: &emptyTemplate,
   356  				OutputTemplate: &emptyTemplate,
   357  			},
   358  		},
   359  		"success when Auth provided": {
   360  			inEntity: &webhook.Entity{
   361  				ID:            "givenID",
   362  				ApplicationID: repo.NewValidNullableString("appID"),
   363  				Auth: sql.NullString{
   364  					Valid:  true,
   365  					String: string(b),
   366  				},
   367  			},
   368  			expectedModel: &model.Webhook{
   369  				ID:         "givenID",
   370  				ObjectID:   "appID",
   371  				ObjectType: model.ApplicationWebhookReference,
   372  				Auth:       fixBasicAuth(),
   373  			},
   374  		},
   375  		"got error on unmarshaling JSON": {
   376  			inEntity: &webhook.Entity{
   377  				Auth: sql.NullString{
   378  					Valid:  true,
   379  					String: "it is not even a proper JSON!",
   380  				},
   381  			},
   382  			expectedErr: errors.New("while unmarshaling Auth: invalid character 'i' looking for beginning of value"),
   383  		},
   384  	}
   385  
   386  	for tn, tc := range testCases {
   387  		t.Run(tn, func(t *testing.T) {
   388  			actual, err := sut.FromEntity(tc.inEntity)
   389  			if tc.expectedErr != nil {
   390  				require.EqualError(t, err, tc.expectedErr.Error())
   391  				return
   392  			}
   393  			require.NoError(t, err)
   394  			assert.Equal(t, tc.expectedModel, actual)
   395  		})
   396  	}
   397  }