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