code.gitea.io/gitea@v1.21.7/models/webhook/webhook_test.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package webhook
     5  
     6  import (
     7  	"context"
     8  	"testing"
     9  	"time"
    10  
    11  	"code.gitea.io/gitea/models/db"
    12  	"code.gitea.io/gitea/models/unittest"
    13  	"code.gitea.io/gitea/modules/json"
    14  	api "code.gitea.io/gitea/modules/structs"
    15  	"code.gitea.io/gitea/modules/timeutil"
    16  	"code.gitea.io/gitea/modules/util"
    17  	webhook_module "code.gitea.io/gitea/modules/webhook"
    18  
    19  	"github.com/stretchr/testify/assert"
    20  )
    21  
    22  func TestHookContentType_Name(t *testing.T) {
    23  	assert.Equal(t, "json", ContentTypeJSON.Name())
    24  	assert.Equal(t, "form", ContentTypeForm.Name())
    25  }
    26  
    27  func TestIsValidHookContentType(t *testing.T) {
    28  	assert.True(t, IsValidHookContentType("json"))
    29  	assert.True(t, IsValidHookContentType("form"))
    30  	assert.False(t, IsValidHookContentType("invalid"))
    31  }
    32  
    33  func TestWebhook_History(t *testing.T) {
    34  	assert.NoError(t, unittest.PrepareTestDatabase())
    35  	webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
    36  	tasks, err := webhook.History(0)
    37  	assert.NoError(t, err)
    38  	if assert.Len(t, tasks, 1) {
    39  		assert.Equal(t, int64(1), tasks[0].ID)
    40  	}
    41  
    42  	webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
    43  	tasks, err = webhook.History(0)
    44  	assert.NoError(t, err)
    45  	assert.Len(t, tasks, 0)
    46  }
    47  
    48  func TestWebhook_UpdateEvent(t *testing.T) {
    49  	assert.NoError(t, unittest.PrepareTestDatabase())
    50  	webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
    51  	hookEvent := &webhook_module.HookEvent{
    52  		PushOnly:       true,
    53  		SendEverything: false,
    54  		ChooseEvents:   false,
    55  		HookEvents: webhook_module.HookEvents{
    56  			Create:      false,
    57  			Push:        true,
    58  			PullRequest: false,
    59  		},
    60  	}
    61  	webhook.HookEvent = hookEvent
    62  	assert.NoError(t, webhook.UpdateEvent())
    63  	assert.NotEmpty(t, webhook.Events)
    64  	actualHookEvent := &webhook_module.HookEvent{}
    65  	assert.NoError(t, json.Unmarshal([]byte(webhook.Events), actualHookEvent))
    66  	assert.Equal(t, *hookEvent, *actualHookEvent)
    67  }
    68  
    69  func TestWebhook_EventsArray(t *testing.T) {
    70  	assert.Equal(t, []string{
    71  		"create", "delete", "fork", "push",
    72  		"issues", "issue_assign", "issue_label", "issue_milestone", "issue_comment",
    73  		"pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone",
    74  		"pull_request_comment", "pull_request_review_approved", "pull_request_review_rejected",
    75  		"pull_request_review_comment", "pull_request_sync", "wiki", "repository", "release",
    76  		"package", "pull_request_review_request",
    77  	},
    78  		(&Webhook{
    79  			HookEvent: &webhook_module.HookEvent{SendEverything: true},
    80  		}).EventsArray(),
    81  	)
    82  
    83  	assert.Equal(t, []string{"push"},
    84  		(&Webhook{
    85  			HookEvent: &webhook_module.HookEvent{PushOnly: true},
    86  		}).EventsArray(),
    87  	)
    88  }
    89  
    90  func TestCreateWebhook(t *testing.T) {
    91  	hook := &Webhook{
    92  		RepoID:      3,
    93  		URL:         "www.example.com/unit_test",
    94  		ContentType: ContentTypeJSON,
    95  		Events:      `{"push_only":false,"send_everything":false,"choose_events":false,"events":{"create":false,"push":true,"pull_request":true}}`,
    96  	}
    97  	unittest.AssertNotExistsBean(t, hook)
    98  	assert.NoError(t, CreateWebhook(db.DefaultContext, hook))
    99  	unittest.AssertExistsAndLoadBean(t, hook)
   100  }
   101  
   102  func TestGetWebhookByRepoID(t *testing.T) {
   103  	assert.NoError(t, unittest.PrepareTestDatabase())
   104  	hook, err := GetWebhookByRepoID(db.DefaultContext, 1, 1)
   105  	assert.NoError(t, err)
   106  	assert.Equal(t, int64(1), hook.ID)
   107  
   108  	_, err = GetWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
   109  	assert.Error(t, err)
   110  	assert.True(t, IsErrWebhookNotExist(err))
   111  }
   112  
   113  func TestGetWebhookByOwnerID(t *testing.T) {
   114  	assert.NoError(t, unittest.PrepareTestDatabase())
   115  	hook, err := GetWebhookByOwnerID(db.DefaultContext, 3, 3)
   116  	assert.NoError(t, err)
   117  	assert.Equal(t, int64(3), hook.ID)
   118  
   119  	_, err = GetWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
   120  	assert.Error(t, err)
   121  	assert.True(t, IsErrWebhookNotExist(err))
   122  }
   123  
   124  func TestGetActiveWebhooksByRepoID(t *testing.T) {
   125  	assert.NoError(t, unittest.PrepareTestDatabase())
   126  	hooks, err := ListWebhooksByOpts(db.DefaultContext, &ListWebhookOptions{RepoID: 1, IsActive: util.OptionalBoolTrue})
   127  	assert.NoError(t, err)
   128  	if assert.Len(t, hooks, 1) {
   129  		assert.Equal(t, int64(1), hooks[0].ID)
   130  		assert.True(t, hooks[0].IsActive)
   131  	}
   132  }
   133  
   134  func TestGetWebhooksByRepoID(t *testing.T) {
   135  	assert.NoError(t, unittest.PrepareTestDatabase())
   136  	hooks, err := ListWebhooksByOpts(db.DefaultContext, &ListWebhookOptions{RepoID: 1})
   137  	assert.NoError(t, err)
   138  	if assert.Len(t, hooks, 2) {
   139  		assert.Equal(t, int64(1), hooks[0].ID)
   140  		assert.Equal(t, int64(2), hooks[1].ID)
   141  	}
   142  }
   143  
   144  func TestGetActiveWebhooksByOwnerID(t *testing.T) {
   145  	assert.NoError(t, unittest.PrepareTestDatabase())
   146  	hooks, err := ListWebhooksByOpts(db.DefaultContext, &ListWebhookOptions{OwnerID: 3, IsActive: util.OptionalBoolTrue})
   147  	assert.NoError(t, err)
   148  	if assert.Len(t, hooks, 1) {
   149  		assert.Equal(t, int64(3), hooks[0].ID)
   150  		assert.True(t, hooks[0].IsActive)
   151  	}
   152  }
   153  
   154  func TestGetWebhooksByOwnerID(t *testing.T) {
   155  	assert.NoError(t, unittest.PrepareTestDatabase())
   156  	hooks, err := ListWebhooksByOpts(db.DefaultContext, &ListWebhookOptions{OwnerID: 3})
   157  	assert.NoError(t, err)
   158  	if assert.Len(t, hooks, 1) {
   159  		assert.Equal(t, int64(3), hooks[0].ID)
   160  		assert.True(t, hooks[0].IsActive)
   161  	}
   162  }
   163  
   164  func TestUpdateWebhook(t *testing.T) {
   165  	assert.NoError(t, unittest.PrepareTestDatabase())
   166  	hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
   167  	hook.IsActive = true
   168  	hook.ContentType = ContentTypeForm
   169  	unittest.AssertNotExistsBean(t, hook)
   170  	assert.NoError(t, UpdateWebhook(hook))
   171  	unittest.AssertExistsAndLoadBean(t, hook)
   172  }
   173  
   174  func TestDeleteWebhookByRepoID(t *testing.T) {
   175  	assert.NoError(t, unittest.PrepareTestDatabase())
   176  	unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1})
   177  	assert.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2))
   178  	unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1})
   179  
   180  	err := DeleteWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
   181  	assert.Error(t, err)
   182  	assert.True(t, IsErrWebhookNotExist(err))
   183  }
   184  
   185  func TestDeleteWebhookByOwnerID(t *testing.T) {
   186  	assert.NoError(t, unittest.PrepareTestDatabase())
   187  	unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3})
   188  	assert.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3))
   189  	unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3})
   190  
   191  	err := DeleteWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
   192  	assert.Error(t, err)
   193  	assert.True(t, IsErrWebhookNotExist(err))
   194  }
   195  
   196  func TestHookTasks(t *testing.T) {
   197  	assert.NoError(t, unittest.PrepareTestDatabase())
   198  	hookTasks, err := HookTasks(1, 1)
   199  	assert.NoError(t, err)
   200  	if assert.Len(t, hookTasks, 1) {
   201  		assert.Equal(t, int64(1), hookTasks[0].ID)
   202  	}
   203  
   204  	hookTasks, err = HookTasks(unittest.NonexistentID, 1)
   205  	assert.NoError(t, err)
   206  	assert.Len(t, hookTasks, 0)
   207  }
   208  
   209  func TestCreateHookTask(t *testing.T) {
   210  	assert.NoError(t, unittest.PrepareTestDatabase())
   211  	hookTask := &HookTask{
   212  		HookID:    3,
   213  		Payloader: &api.PushPayload{},
   214  	}
   215  	unittest.AssertNotExistsBean(t, hookTask)
   216  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   217  	assert.NoError(t, err)
   218  	unittest.AssertExistsAndLoadBean(t, hookTask)
   219  }
   220  
   221  func TestUpdateHookTask(t *testing.T) {
   222  	assert.NoError(t, unittest.PrepareTestDatabase())
   223  
   224  	hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1})
   225  	hook.PayloadContent = "new payload content"
   226  	hook.IsDelivered = true
   227  	unittest.AssertNotExistsBean(t, hook)
   228  	assert.NoError(t, UpdateHookTask(hook))
   229  	unittest.AssertExistsAndLoadBean(t, hook)
   230  }
   231  
   232  func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
   233  	assert.NoError(t, unittest.PrepareTestDatabase())
   234  	hookTask := &HookTask{
   235  		HookID:      3,
   236  		Payloader:   &api.PushPayload{},
   237  		IsDelivered: true,
   238  		Delivered:   timeutil.TimeStampNanoNow(),
   239  	}
   240  	unittest.AssertNotExistsBean(t, hookTask)
   241  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   242  	assert.NoError(t, err)
   243  	unittest.AssertExistsAndLoadBean(t, hookTask)
   244  
   245  	assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
   246  	unittest.AssertNotExistsBean(t, hookTask)
   247  }
   248  
   249  func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) {
   250  	assert.NoError(t, unittest.PrepareTestDatabase())
   251  	hookTask := &HookTask{
   252  		HookID:      4,
   253  		Payloader:   &api.PushPayload{},
   254  		IsDelivered: false,
   255  	}
   256  	unittest.AssertNotExistsBean(t, hookTask)
   257  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   258  	assert.NoError(t, err)
   259  	unittest.AssertExistsAndLoadBean(t, hookTask)
   260  
   261  	assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
   262  	unittest.AssertExistsAndLoadBean(t, hookTask)
   263  }
   264  
   265  func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
   266  	assert.NoError(t, unittest.PrepareTestDatabase())
   267  	hookTask := &HookTask{
   268  		HookID:      4,
   269  		Payloader:   &api.PushPayload{},
   270  		IsDelivered: true,
   271  		Delivered:   timeutil.TimeStampNanoNow(),
   272  	}
   273  	unittest.AssertNotExistsBean(t, hookTask)
   274  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   275  	assert.NoError(t, err)
   276  	unittest.AssertExistsAndLoadBean(t, hookTask)
   277  
   278  	assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 1))
   279  	unittest.AssertExistsAndLoadBean(t, hookTask)
   280  }
   281  
   282  func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
   283  	assert.NoError(t, unittest.PrepareTestDatabase())
   284  	hookTask := &HookTask{
   285  		HookID:      3,
   286  		Payloader:   &api.PushPayload{},
   287  		IsDelivered: true,
   288  		Delivered:   timeutil.TimeStampNano(time.Now().AddDate(0, 0, -8).UnixNano()),
   289  	}
   290  	unittest.AssertNotExistsBean(t, hookTask)
   291  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   292  	assert.NoError(t, err)
   293  	unittest.AssertExistsAndLoadBean(t, hookTask)
   294  
   295  	assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
   296  	unittest.AssertNotExistsBean(t, hookTask)
   297  }
   298  
   299  func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) {
   300  	assert.NoError(t, unittest.PrepareTestDatabase())
   301  	hookTask := &HookTask{
   302  		HookID:      4,
   303  		Payloader:   &api.PushPayload{},
   304  		IsDelivered: false,
   305  	}
   306  	unittest.AssertNotExistsBean(t, hookTask)
   307  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   308  	assert.NoError(t, err)
   309  	unittest.AssertExistsAndLoadBean(t, hookTask)
   310  
   311  	assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
   312  	unittest.AssertExistsAndLoadBean(t, hookTask)
   313  }
   314  
   315  func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *testing.T) {
   316  	assert.NoError(t, unittest.PrepareTestDatabase())
   317  	hookTask := &HookTask{
   318  		HookID:      4,
   319  		Payloader:   &api.PushPayload{},
   320  		IsDelivered: true,
   321  		Delivered:   timeutil.TimeStampNano(time.Now().AddDate(0, 0, -6).UnixNano()),
   322  	}
   323  	unittest.AssertNotExistsBean(t, hookTask)
   324  	_, err := CreateHookTask(db.DefaultContext, hookTask)
   325  	assert.NoError(t, err)
   326  	unittest.AssertExistsAndLoadBean(t, hookTask)
   327  
   328  	assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
   329  	unittest.AssertExistsAndLoadBean(t, hookTask)
   330  }