Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
581 lines
19 KiB
Go
581 lines
19 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
)
|
|
|
|
func TestGetJob(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
status := &model.Job{
|
|
Id: model.NewId(),
|
|
Status: model.NewId(),
|
|
}
|
|
|
|
_, err := th.App.Srv().Store().Job().Save(status)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
_, err = th.App.Srv().Store().Job().Delete(status.Id)
|
|
require.NoError(t, err)
|
|
}()
|
|
|
|
received, appErr := th.App.GetJob(th.Context, status.Id)
|
|
require.Nil(t, appErr)
|
|
require.Equal(t, status, received, "incorrect job status received")
|
|
}
|
|
|
|
func TestSessionHasPermissionToCreateJob(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
jobs := []model.Job{
|
|
{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeDataRetention,
|
|
CreateAt: 999,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeMessageExport,
|
|
CreateAt: 1001,
|
|
},
|
|
}
|
|
|
|
testCases := []struct {
|
|
Job model.Job
|
|
PermissionRequired *model.Permission
|
|
}{
|
|
{
|
|
Job: jobs[0],
|
|
PermissionRequired: model.PermissionCreateDataRetentionJob,
|
|
},
|
|
{
|
|
Job: jobs[1],
|
|
PermissionRequired: model.PermissionCreateComplianceExportJob,
|
|
},
|
|
}
|
|
|
|
session := model.Session{
|
|
Roles: model.SystemUserRoleId + " " + model.SystemAdminRoleId,
|
|
}
|
|
|
|
// Check to see if admin has permission to all the jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job)
|
|
assert.Equal(t, true, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
|
|
session = model.Session{
|
|
Roles: model.SystemUserRoleId + " " + model.SystemReadOnlyAdminRoleId,
|
|
}
|
|
|
|
// Initially the system read only admin should not have access to create these jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job)
|
|
assert.Equal(t, false, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
|
|
role, _ := th.App.GetRoleByName(RequestContextWithMaster(th.Context), model.SystemReadOnlyAdminRoleId)
|
|
|
|
role.Permissions = append(role.Permissions, model.PermissionCreateDataRetentionJob.Id)
|
|
role.Permissions = append(role.Permissions, model.PermissionCreateComplianceExportJob.Id)
|
|
|
|
_, err := th.App.UpdateRole(role)
|
|
require.Nil(t, err)
|
|
|
|
// Now system read only admin should have ability to create all jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(session, &testCase.Job)
|
|
assert.Equal(t, true, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
}
|
|
|
|
func TestSessionHasPermissionToCreateAccessControlSyncJob(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
// Create a private channel and make BasicUser a channel admin
|
|
privateChannel := th.CreatePrivateChannel(th.Context, th.BasicTeam)
|
|
_, err := th.App.AddUserToChannel(th.Context, th.BasicUser, privateChannel, false)
|
|
require.Nil(t, err)
|
|
|
|
// Update BasicUser to have channel admin permissions for this channel
|
|
_, err = th.App.UpdateChannelMemberRoles(th.Context, privateChannel.Id, th.BasicUser.Id,
|
|
model.ChannelUserRoleId+" "+model.ChannelAdminRoleId)
|
|
require.Nil(t, err)
|
|
|
|
job := model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
}
|
|
|
|
t.Run("system admin can create access control sync job", func(t *testing.T) {
|
|
adminSession := model.Session{
|
|
UserId: th.SystemAdminUser.Id,
|
|
Roles: model.SystemUserRoleId + " " + model.SystemAdminRoleId,
|
|
}
|
|
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(adminSession, &job)
|
|
assert.True(t, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, model.PermissionManageSystem.Id, permissionRequired.Id)
|
|
})
|
|
|
|
t.Run("channel admin can create access control sync job for their channel", func(t *testing.T) {
|
|
channelAdminSession := model.Session{
|
|
UserId: th.BasicUser.Id,
|
|
Roles: model.SystemUserRoleId,
|
|
}
|
|
|
|
// Create job with channel-specific data (like channel admin would)
|
|
jobWithChannelData := model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Data: model.StringMap{
|
|
"policy_id": privateChannel.Id, // Channel admin jobs have policy_id = channelID
|
|
},
|
|
}
|
|
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(channelAdminSession, &jobWithChannelData)
|
|
assert.True(t, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, model.PermissionManageChannelAccessRules.Id, permissionRequired.Id)
|
|
})
|
|
|
|
t.Run("channel admin cannot create access control sync job for other channel", func(t *testing.T) {
|
|
// Create another private channel that BasicUser is NOT admin of
|
|
otherChannel := th.CreatePrivateChannel(th.Context, th.BasicTeam)
|
|
|
|
// EXPLICITLY remove channel admin role from BasicUser for otherChannel
|
|
// (CreatePrivateChannel might auto-add admin roles)
|
|
_, err := th.App.UpdateChannelMemberRoles(th.Context, otherChannel.Id, th.BasicUser.Id, model.ChannelUserRoleId)
|
|
require.Nil(t, err)
|
|
|
|
// Verify BasicUser is NOT a channel admin of otherChannel
|
|
otherChannelMember, err := th.App.GetChannelMember(th.Context, otherChannel.Id, th.BasicUser.Id)
|
|
require.Nil(t, err)
|
|
require.NotNil(t, otherChannelMember)
|
|
// BasicUser should only be a regular member, not admin
|
|
assert.Equal(t, model.ChannelUserRoleId, otherChannelMember.Roles)
|
|
|
|
channelAdminSession := model.Session{
|
|
UserId: th.BasicUser.Id,
|
|
Roles: model.SystemUserRoleId,
|
|
}
|
|
|
|
// Try to create job for channel they don't admin
|
|
jobWithOtherChannelData := model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Data: model.StringMap{
|
|
"policy_id": otherChannel.Id,
|
|
},
|
|
}
|
|
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(channelAdminSession, &jobWithOtherChannelData)
|
|
assert.False(t, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, model.PermissionManageSystem.Id, permissionRequired.Id)
|
|
})
|
|
|
|
t.Run("regular user cannot create access control sync job", func(t *testing.T) {
|
|
regularUser := th.CreateUser()
|
|
regularUserSession := model.Session{
|
|
UserId: regularUser.Id,
|
|
Roles: model.SystemUserRoleId,
|
|
}
|
|
|
|
// Regular user tries to create job with channel data
|
|
jobWithChannelData := model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Data: model.StringMap{
|
|
"policy_id": privateChannel.Id,
|
|
},
|
|
}
|
|
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToCreateJob(regularUserSession, &jobWithChannelData)
|
|
assert.False(t, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, model.PermissionManageSystem.Id, permissionRequired.Id)
|
|
})
|
|
}
|
|
|
|
func TestCreateAccessControlSyncJob(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t).InitBasic()
|
|
defer th.TearDown()
|
|
|
|
t.Run("cancels pending job and creates new one", func(t *testing.T) {
|
|
// Create an existing pending job manually in the store
|
|
existingJob := &model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Status: model.JobStatusPending,
|
|
Data: map[string]string{
|
|
"policy_id": "channel456",
|
|
},
|
|
}
|
|
_, err := th.App.Srv().Store().Job().Save(existingJob)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
_, stErr := th.App.Srv().Store().Job().Delete(existingJob.Id)
|
|
require.NoError(t, stErr)
|
|
})
|
|
|
|
// Test the cancellation logic by calling the method directly
|
|
existingJobs, storeErr := th.App.Srv().Store().Job().GetByTypeAndData(th.Context, model.JobTypeAccessControlSync, map[string]string{
|
|
"policy_id": "channel456",
|
|
}, false, model.JobStatusPending, model.JobStatusInProgress)
|
|
require.NoError(t, storeErr)
|
|
require.Len(t, existingJobs, 1)
|
|
|
|
// Verify that the store method finds the job
|
|
assert.Equal(t, existingJob.Id, existingJobs[0].Id)
|
|
assert.Equal(t, model.JobStatusPending, existingJobs[0].Status)
|
|
|
|
// Test the cancellation logic directly
|
|
for _, job := range existingJobs {
|
|
if job.Status == model.JobStatusPending || job.Status == model.JobStatusInProgress {
|
|
appErr := th.App.CancelJob(th.Context, job.Id)
|
|
require.Nil(t, appErr)
|
|
}
|
|
}
|
|
|
|
// Verify that the job was cancelled
|
|
updatedJob, getErr := th.App.Srv().Store().Job().Get(th.Context, existingJob.Id)
|
|
require.NoError(t, getErr)
|
|
// Job should be either cancel_requested or canceled (async process)
|
|
assert.Contains(t, []string{model.JobStatusCancelRequested, model.JobStatusCanceled}, updatedJob.Status)
|
|
})
|
|
|
|
t.Run("cancels in-progress job and creates new one", func(t *testing.T) {
|
|
// Create an existing in-progress job
|
|
existingJob := &model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Status: model.JobStatusInProgress,
|
|
Data: map[string]string{
|
|
"policy_id": "channel789",
|
|
},
|
|
}
|
|
_, err := th.App.Srv().Store().Job().Save(existingJob)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
_, stErr := th.App.Srv().Store().Job().Delete(existingJob.Id)
|
|
require.NoError(t, stErr)
|
|
})
|
|
|
|
// Test that GetByTypeAndData finds the in-progress job
|
|
existingJobs, storeErr := th.App.Srv().Store().Job().GetByTypeAndData(th.Context, model.JobTypeAccessControlSync, map[string]string{
|
|
"policy_id": "channel789",
|
|
}, false, model.JobStatusPending, model.JobStatusInProgress)
|
|
require.NoError(t, storeErr)
|
|
require.Len(t, existingJobs, 1)
|
|
assert.Equal(t, model.JobStatusInProgress, existingJobs[0].Status)
|
|
|
|
// Test cancellation of in-progress job
|
|
appErr := th.App.CancelJob(th.Context, existingJob.Id)
|
|
require.Nil(t, appErr)
|
|
|
|
// Verify cancellation was requested (job cancellation is asynchronous)
|
|
updatedJob, getErr := th.App.Srv().Store().Job().Get(th.Context, existingJob.Id)
|
|
require.NoError(t, getErr)
|
|
// Job should be either cancel_requested or canceled (async process)
|
|
assert.Contains(t, []string{model.JobStatusCancelRequested, model.JobStatusCanceled}, updatedJob.Status)
|
|
})
|
|
|
|
t.Run("leaves completed jobs alone", func(t *testing.T) {
|
|
// Create an existing completed job
|
|
existingJob := &model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Status: model.JobStatusSuccess,
|
|
Data: map[string]string{
|
|
"policy_id": "channel101",
|
|
},
|
|
}
|
|
_, err := th.App.Srv().Store().Job().Save(existingJob)
|
|
require.NoError(t, err)
|
|
t.Cleanup(func() {
|
|
_, stErr := th.App.Srv().Store().Job().Delete(existingJob.Id)
|
|
require.NoError(t, stErr)
|
|
})
|
|
|
|
// Test that GetByTypeAndData finds the completed job
|
|
existingJobs, storeErr := th.App.Srv().Store().Job().GetByTypeAndData(th.Context, model.JobTypeAccessControlSync, map[string]string{
|
|
"policy_id": "channel101",
|
|
}, false)
|
|
require.NoError(t, storeErr)
|
|
require.Len(t, existingJobs, 1)
|
|
assert.Equal(t, model.JobStatusSuccess, existingJobs[0].Status)
|
|
|
|
// Test that we don't cancel completed jobs (logic test)
|
|
shouldCancel := existingJob.Status == model.JobStatusPending || existingJob.Status == model.JobStatusInProgress
|
|
assert.False(t, shouldCancel, "Should not cancel completed jobs")
|
|
|
|
// Verify the job status is unchanged
|
|
updatedJob, getErr := th.App.Srv().Store().Job().Get(th.Context, existingJob.Id)
|
|
require.NoError(t, getErr)
|
|
assert.Equal(t, model.JobStatusSuccess, updatedJob.Status)
|
|
})
|
|
|
|
// Test deduplication logic with status filtering to ensure database optimization works correctly
|
|
|
|
t.Run("deduplication respects status filtering", func(t *testing.T) {
|
|
// Create jobs with different statuses
|
|
pendingJob := &model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Status: model.JobStatusPending,
|
|
Data: map[string]string{"policy_id": "channel999"},
|
|
}
|
|
|
|
completedJob := &model.Job{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeAccessControlSync,
|
|
Status: model.JobStatusSuccess,
|
|
Data: map[string]string{"policy_id": "channel999"},
|
|
}
|
|
|
|
for _, job := range []*model.Job{pendingJob, completedJob} {
|
|
_, err := th.App.Srv().Store().Job().Save(job)
|
|
require.NoError(t, err)
|
|
|
|
// Capture job ID to avoid closure variable capture issue
|
|
jobID := job.Id
|
|
t.Cleanup(func() {
|
|
_, stErr := th.App.Srv().Store().Job().Delete(jobID)
|
|
require.NoError(t, stErr)
|
|
})
|
|
}
|
|
|
|
// Verify status filtering returns only active jobs
|
|
activeJobs, err := th.App.Srv().Store().Job().GetByTypeAndData(
|
|
th.Context,
|
|
model.JobTypeAccessControlSync,
|
|
map[string]string{"policy_id": "channel999"},
|
|
false,
|
|
model.JobStatusPending, model.JobStatusInProgress, // Only active statuses
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, activeJobs, 1, "Should only find active jobs (pending/in-progress)")
|
|
assert.Equal(t, pendingJob.Id, activeJobs[0].Id, "Should find the pending job")
|
|
|
|
// Verify all jobs are returned when no status filter is provided
|
|
allJobs, err := th.App.Srv().Store().Job().GetByTypeAndData(
|
|
th.Context,
|
|
model.JobTypeAccessControlSync,
|
|
map[string]string{"policy_id": "channel999"},
|
|
false, // No status filter
|
|
)
|
|
require.NoError(t, err)
|
|
require.Len(t, allJobs, 2, "Should find all jobs when no status filter")
|
|
})
|
|
}
|
|
|
|
func TestSessionHasPermissionToReadJob(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
jobs := []model.Job{
|
|
{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeDataRetention,
|
|
CreateAt: 999,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: model.JobTypeMessageExport,
|
|
CreateAt: 1001,
|
|
},
|
|
}
|
|
testCases := []struct {
|
|
Job model.Job
|
|
PermissionRequired *model.Permission
|
|
}{
|
|
{
|
|
Job: jobs[0],
|
|
PermissionRequired: model.PermissionReadDataRetentionJob,
|
|
},
|
|
{
|
|
Job: jobs[1],
|
|
PermissionRequired: model.PermissionReadComplianceExportJob,
|
|
},
|
|
}
|
|
|
|
session := model.Session{
|
|
Roles: model.SystemUserRoleId + " " + model.SystemAdminRoleId,
|
|
}
|
|
|
|
// Check to see if admin has permission to all the jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type)
|
|
assert.Equal(t, true, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
|
|
session = model.Session{
|
|
Roles: model.SystemUserRoleId + " " + model.SystemManagerRoleId,
|
|
}
|
|
|
|
// Initially the system manager should not have access to read these jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type)
|
|
assert.Equal(t, false, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
|
|
role, _ := th.App.GetRoleByName(RequestContextWithMaster(th.Context), model.SystemManagerRoleId)
|
|
|
|
role.Permissions = append(role.Permissions, model.PermissionReadDataRetentionJob.Id)
|
|
|
|
_, err := th.App.UpdateRole(role)
|
|
require.Nil(t, err)
|
|
|
|
// Now system manager should have ability to read data retention jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type)
|
|
expectedHasPermission := testCase.Job.Type == model.JobTypeDataRetention
|
|
assert.Equal(t, expectedHasPermission, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
|
|
role.Permissions = append(role.Permissions, model.PermissionReadComplianceExportJob.Id)
|
|
|
|
_, err = th.App.UpdateRole(role)
|
|
require.Nil(t, err)
|
|
|
|
// Now system read only admin should have ability to create all jobs
|
|
for _, testCase := range testCases {
|
|
hasPermission, permissionRequired := th.App.SessionHasPermissionToReadJob(session, testCase.Job.Type)
|
|
assert.Equal(t, true, hasPermission)
|
|
require.NotNil(t, permissionRequired)
|
|
assert.Equal(t, testCase.PermissionRequired.Id, permissionRequired.Id)
|
|
}
|
|
}
|
|
|
|
func TestGetJobByType(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
jobType := model.NewId()
|
|
|
|
statuses := []*model.Job{
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType,
|
|
CreateAt: 1000,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType,
|
|
CreateAt: 999,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType,
|
|
CreateAt: 1001,
|
|
},
|
|
}
|
|
|
|
for _, status := range statuses {
|
|
_, err := th.App.Srv().Store().Job().Save(status)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
_, err = th.App.Srv().Store().Job().Delete(status.Id)
|
|
require.NoError(t, err)
|
|
}()
|
|
}
|
|
|
|
received, err := th.App.GetJobsByTypePage(th.Context, jobType, 0, 2)
|
|
require.Nil(t, err)
|
|
require.Len(t, received, 2, "received wrong number of statuses")
|
|
require.Equal(t, statuses[2], received[0], "should've received newest job first")
|
|
require.Equal(t, statuses[0], received[1], "should've received second newest job second")
|
|
|
|
received, err = th.App.GetJobsByTypePage(th.Context, jobType, 1, 2)
|
|
require.Nil(t, err)
|
|
require.Len(t, received, 1, "received wrong number of statuses")
|
|
require.Equal(t, statuses[1], received[0], "should've received oldest job last")
|
|
}
|
|
|
|
func TestGetJobsByTypes(t *testing.T) {
|
|
mainHelper.Parallel(t)
|
|
th := Setup(t)
|
|
defer th.TearDown()
|
|
|
|
jobType := model.NewId()
|
|
jobType1 := model.NewId()
|
|
jobType2 := model.NewId()
|
|
|
|
statuses := []*model.Job{
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType,
|
|
CreateAt: 1000,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType1,
|
|
CreateAt: 999,
|
|
},
|
|
{
|
|
Id: model.NewId(),
|
|
Type: jobType2,
|
|
CreateAt: 1001,
|
|
},
|
|
}
|
|
|
|
for _, status := range statuses {
|
|
_, err := th.App.Srv().Store().Job().Save(status)
|
|
require.NoError(t, err)
|
|
defer func() {
|
|
_, err = th.App.Srv().Store().Job().Delete(status.Id)
|
|
require.NoError(t, err)
|
|
}()
|
|
}
|
|
|
|
jobTypes := []string{jobType, jobType1, jobType2}
|
|
received, err := th.App.GetJobsByTypesPage(th.Context, jobTypes, 0, 2)
|
|
require.Nil(t, err)
|
|
require.Len(t, received, 2, "received wrong number of jobs")
|
|
require.Equal(t, statuses[2], received[0], "should've received newest job first")
|
|
require.Equal(t, statuses[0], received[1], "should've received second newest job second")
|
|
|
|
received, err = th.App.GetJobsByTypesPage(th.Context, jobTypes, 1, 2)
|
|
require.Nil(t, err)
|
|
require.Len(t, received, 1, "received wrong number of jobs")
|
|
require.Equal(t, statuses[1], received[0], "should've received oldest job last")
|
|
|
|
jobTypes = []string{jobType1, jobType2}
|
|
received, err = th.App.GetJobsByTypesPage(th.Context, jobTypes, 0, 3)
|
|
require.Nil(t, err)
|
|
require.Len(t, received, 2, "received wrong number of jobs")
|
|
require.Equal(t, statuses[2], received[0], "received wrong job type")
|
|
require.Equal(t, statuses[1], received[1], "received wrong job type")
|
|
}
|