2017-02-09 09:39:26 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2017-02-09 09:39:26 +03:00
2022-06-13 12:37:59 +03:00
package issues_test
2017-02-09 09:39:26 +03:00
import (
2017-06-12 18:01:09 +03:00
"sort"
2017-02-09 09:39:26 +03:00
"testing"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2022-06-13 12:37:59 +03:00
issues_model "code.gitea.io/gitea/models/issues"
2021-12-10 04:27:50 +03:00
repo_model "code.gitea.io/gitea/models/repo"
2021-11-12 17:36:47 +03:00
"code.gitea.io/gitea/models/unittest"
2024-03-02 18:42:31 +03:00
"code.gitea.io/gitea/modules/optional"
2020-07-28 14:30:40 +03:00
"code.gitea.io/gitea/modules/setting"
2019-05-11 13:21:34 +03:00
api "code.gitea.io/gitea/modules/structs"
2022-06-13 12:37:59 +03:00
"code.gitea.io/gitea/modules/timeutil"
2017-02-09 09:39:26 +03:00
"github.com/stretchr/testify/assert"
)
func TestMilestone_State ( t * testing . T ) {
2022-06-13 12:37:59 +03:00
assert . Equal ( t , api . StateOpen , ( & issues_model . Milestone { IsClosed : false } ) . State ( ) )
assert . Equal ( t , api . StateClosed , ( & issues_model . Milestone { IsClosed : true } ) . State ( ) )
2017-02-09 09:39:26 +03:00
}
func TestGetMilestoneByRepoID ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-09 09:39:26 +03:00
2022-06-13 12:37:59 +03:00
milestone , err := issues_model . GetMilestoneByRepoID ( db . DefaultContext , 1 , 1 )
2017-02-09 09:39:26 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , 1 , milestone . ID )
assert . EqualValues ( t , 1 , milestone . RepoID )
2022-06-13 12:37:59 +03:00
_ , err = issues_model . GetMilestoneByRepoID ( db . DefaultContext , unittest . NonexistentID , unittest . NonexistentID )
assert . True ( t , issues_model . IsErrMilestoneNotExist ( err ) )
2017-02-09 09:39:26 +03:00
}
func TestGetMilestonesByRepoID ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2019-06-06 03:37:45 +03:00
test := func ( repoID int64 , state api . StateType ) {
2024-03-02 18:42:31 +03:00
var isClosed optional . Option [ bool ]
2023-12-11 11:56:48 +03:00
switch state {
case api . StateClosed , api . StateOpen :
2024-03-02 18:42:31 +03:00
isClosed = optional . Some ( state == api . StateClosed )
2023-12-11 11:56:48 +03:00
}
2022-08-16 05:22:25 +03:00
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : repoID } )
2023-12-11 11:56:48 +03:00
milestones , err := db . Find [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
RepoID : repo . ID ,
IsClosed : isClosed ,
2020-07-28 14:30:40 +03:00
} )
2017-02-09 09:39:26 +03:00
assert . NoError ( t , err )
2019-06-06 03:37:45 +03:00
var n int
switch state {
case api . StateClosed :
n = repo . NumClosedMilestones
case api . StateAll :
n = repo . NumMilestones
case api . StateOpen :
fallthrough
default :
n = repo . NumOpenMilestones
}
assert . Len ( t , milestones , n )
2017-02-09 09:39:26 +03:00
for _ , milestone := range milestones {
assert . EqualValues ( t , repoID , milestone . RepoID )
}
}
2019-06-06 03:37:45 +03:00
test ( 1 , api . StateOpen )
test ( 1 , api . StateAll )
test ( 1 , api . StateClosed )
test ( 2 , api . StateOpen )
test ( 2 , api . StateAll )
test ( 2 , api . StateClosed )
test ( 3 , api . StateOpen )
test ( 3 , api . StateClosed )
test ( 3 , api . StateAll )
2017-02-09 09:39:26 +03:00
2023-12-11 11:56:48 +03:00
milestones , err := db . Find [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
RepoID : unittest . NonexistentID ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( false ) ,
2020-07-28 14:30:40 +03:00
} )
2017-02-09 09:39:26 +03:00
assert . NoError ( t , err )
assert . Len ( t , milestones , 0 )
}
func TestGetMilestones ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2022-08-16 05:22:25 +03:00
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 } )
2022-06-13 12:37:59 +03:00
test := func ( sortType string , sortCond func ( * issues_model . Milestone ) int ) {
2017-02-09 09:39:26 +03:00
for _ , page := range [ ] int { 0 , 1 } {
2023-12-11 11:56:48 +03:00
milestones , err := db . Find [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
2021-09-24 14:32:56 +03:00
ListOptions : db . ListOptions {
2020-07-28 14:30:40 +03:00
Page : page ,
PageSize : setting . UI . IssuePagingNum ,
} ,
RepoID : repo . ID ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( false ) ,
2020-07-28 14:30:40 +03:00
SortType : sortType ,
} )
2017-02-09 09:39:26 +03:00
assert . NoError ( t , err )
assert . Len ( t , milestones , repo . NumMilestones - repo . NumClosedMilestones )
values := make ( [ ] int , len ( milestones ) )
for i , milestone := range milestones {
values [ i ] = sortCond ( milestone )
}
assert . True ( t , sort . IntsAreSorted ( values ) )
2023-12-11 11:56:48 +03:00
milestones , err = db . Find [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
2021-09-24 14:32:56 +03:00
ListOptions : db . ListOptions {
2020-07-28 14:30:40 +03:00
Page : page ,
PageSize : setting . UI . IssuePagingNum ,
} ,
RepoID : repo . ID ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( true ) ,
2020-07-28 14:30:40 +03:00
Name : "" ,
SortType : sortType ,
} )
2017-02-09 09:39:26 +03:00
assert . NoError ( t , err )
assert . Len ( t , milestones , repo . NumClosedMilestones )
values = make ( [ ] int , len ( milestones ) )
for i , milestone := range milestones {
values [ i ] = sortCond ( milestone )
}
assert . True ( t , sort . IntsAreSorted ( values ) )
}
}
2022-06-13 12:37:59 +03:00
test ( "furthestduedate" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return - int ( milestone . DeadlineUnix )
} )
2022-06-13 12:37:59 +03:00
test ( "leastcomplete" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return milestone . Completeness
} )
2022-06-13 12:37:59 +03:00
test ( "mostcomplete" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return - milestone . Completeness
} )
2022-06-13 12:37:59 +03:00
test ( "leastissues" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return milestone . NumIssues
} )
2022-06-13 12:37:59 +03:00
test ( "mostissues" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return - milestone . NumIssues
} )
2022-06-13 12:37:59 +03:00
test ( "soonestduedate" , func ( milestone * issues_model . Milestone ) int {
2017-02-09 09:39:26 +03:00
return int ( milestone . DeadlineUnix )
} )
}
func TestCountRepoMilestones ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-09 09:39:26 +03:00
test := func ( repoID int64 ) {
2022-08-16 05:22:25 +03:00
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : repoID } )
2023-12-11 11:56:48 +03:00
count , err := db . Count [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
2022-06-13 12:37:59 +03:00
RepoID : repoID ,
} )
2017-12-18 17:06:51 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , repo . NumMilestones , count )
2017-02-09 09:39:26 +03:00
}
test ( 1 )
test ( 2 )
test ( 3 )
2017-12-18 17:06:51 +03:00
2023-12-11 11:56:48 +03:00
count , err := db . Count [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
2022-06-13 12:37:59 +03:00
RepoID : unittest . NonexistentID ,
} )
2017-12-18 17:06:51 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , 0 , count )
2017-02-09 09:39:26 +03:00
}
func TestCountRepoClosedMilestones ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2017-02-09 09:39:26 +03:00
test := func ( repoID int64 ) {
2022-08-16 05:22:25 +03:00
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : repoID } )
2023-12-11 11:56:48 +03:00
count , err := db . Count [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
RepoID : repoID ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( true ) ,
2022-06-13 12:37:59 +03:00
} )
2017-12-18 17:06:51 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , repo . NumClosedMilestones , count )
2017-02-09 09:39:26 +03:00
}
test ( 1 )
test ( 2 )
test ( 3 )
2017-12-18 17:06:51 +03:00
2023-12-11 11:56:48 +03:00
count , err := db . Count [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
RepoID : unittest . NonexistentID ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( true ) ,
2022-06-13 12:37:59 +03:00
} )
2017-12-18 17:06:51 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , 0 , count )
2017-02-09 09:39:26 +03:00
}
2019-12-15 17:20:08 +03:00
func TestCountMilestonesByRepoIDs ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2019-12-15 17:20:08 +03:00
milestonesCount := func ( repoID int64 ) ( int , int ) {
2022-08-16 05:22:25 +03:00
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : repoID } )
2019-12-15 17:20:08 +03:00
return repo . NumOpenMilestones , repo . NumClosedMilestones
}
repo1OpenCount , repo1ClosedCount := milestonesCount ( 1 )
repo2OpenCount , repo2ClosedCount := milestonesCount ( 2 )
2023-12-11 11:56:48 +03:00
openCounts , err := issues_model . CountMilestonesMap ( db . DefaultContext , issues_model . FindMilestoneOptions {
RepoIDs : [ ] int64 { 1 , 2 } ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( false ) ,
2023-12-11 11:56:48 +03:00
} )
2019-12-15 17:20:08 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , repo1OpenCount , openCounts [ 1 ] )
assert . EqualValues ( t , repo2OpenCount , openCounts [ 2 ] )
2023-12-11 11:56:48 +03:00
closedCounts , err := issues_model . CountMilestonesMap ( db . DefaultContext ,
issues_model . FindMilestoneOptions {
RepoIDs : [ ] int64 { 1 , 2 } ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( true ) ,
2023-12-11 11:56:48 +03:00
} )
2019-12-15 17:20:08 +03:00
assert . NoError ( t , err )
assert . EqualValues ( t , repo1ClosedCount , closedCounts [ 1 ] )
assert . EqualValues ( t , repo2ClosedCount , closedCounts [ 2 ] )
}
func TestGetMilestonesByRepoIDs ( t * testing . T ) {
2021-11-12 17:36:47 +03:00
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2022-08-16 05:22:25 +03:00
repo1 := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 1 } )
repo2 := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : 2 } )
2022-06-13 12:37:59 +03:00
test := func ( sortType string , sortCond func ( * issues_model . Milestone ) int ) {
2019-12-15 17:20:08 +03:00
for _ , page := range [ ] int { 0 , 1 } {
2023-12-11 11:56:48 +03:00
openMilestones , err := db . Find [ issues_model . Milestone ] ( db . DefaultContext , issues_model . FindMilestoneOptions {
ListOptions : db . ListOptions {
Page : page ,
PageSize : setting . UI . IssuePagingNum ,
} ,
RepoIDs : [ ] int64 { repo1 . ID , repo2 . ID } ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( false ) ,
2023-12-11 11:56:48 +03:00
SortType : sortType ,
} )
2019-12-15 17:20:08 +03:00
assert . NoError ( t , err )
assert . Len ( t , openMilestones , repo1 . NumOpenMilestones + repo2 . NumOpenMilestones )
values := make ( [ ] int , len ( openMilestones ) )
for i , milestone := range openMilestones {
values [ i ] = sortCond ( milestone )
}
assert . True ( t , sort . IntsAreSorted ( values ) )
2023-12-11 11:56:48 +03:00
closedMilestones , err := db . Find [ issues_model . Milestone ] ( db . DefaultContext ,
issues_model . FindMilestoneOptions {
ListOptions : db . ListOptions {
Page : page ,
PageSize : setting . UI . IssuePagingNum ,
} ,
RepoIDs : [ ] int64 { repo1 . ID , repo2 . ID } ,
2024-03-02 18:42:31 +03:00
IsClosed : optional . Some ( true ) ,
2023-12-11 11:56:48 +03:00
SortType : sortType ,
} )
2019-12-15 17:20:08 +03:00
assert . NoError ( t , err )
assert . Len ( t , closedMilestones , repo1 . NumClosedMilestones + repo2 . NumClosedMilestones )
values = make ( [ ] int , len ( closedMilestones ) )
for i , milestone := range closedMilestones {
values [ i ] = sortCond ( milestone )
}
assert . True ( t , sort . IntsAreSorted ( values ) )
}
}
2022-06-13 12:37:59 +03:00
test ( "furthestduedate" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return - int ( milestone . DeadlineUnix )
} )
2022-06-13 12:37:59 +03:00
test ( "leastcomplete" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return milestone . Completeness
} )
2022-06-13 12:37:59 +03:00
test ( "mostcomplete" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return - milestone . Completeness
} )
2022-06-13 12:37:59 +03:00
test ( "leastissues" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return milestone . NumIssues
} )
2022-06-13 12:37:59 +03:00
test ( "mostissues" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return - milestone . NumIssues
} )
2022-06-13 12:37:59 +03:00
test ( "soonestduedate" , func ( milestone * issues_model . Milestone ) int {
2019-12-15 17:20:08 +03:00
return int ( milestone . DeadlineUnix )
} )
}
2022-06-13 12:37:59 +03:00
func TestNewMilestone ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
milestone := & issues_model . Milestone {
RepoID : 1 ,
Name : "milestoneName" ,
Content : "milestoneContent" ,
}
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . NewMilestone ( db . DefaultContext , milestone ) )
2022-06-13 12:37:59 +03:00
unittest . AssertExistsAndLoadBean ( t , milestone )
unittest . CheckConsistencyFor ( t , & repo_model . Repository { ID : milestone . RepoID } , & issues_model . Milestone { } )
}
func TestChangeMilestoneStatus ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2022-08-16 05:22:25 +03:00
milestone := unittest . AssertExistsAndLoadBean ( t , & issues_model . Milestone { ID : 1 } )
2022-06-13 12:37:59 +03:00
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . ChangeMilestoneStatus ( db . DefaultContext , milestone , true ) )
2022-06-13 12:37:59 +03:00
unittest . AssertExistsAndLoadBean ( t , & issues_model . Milestone { ID : 1 } , "is_closed=1" )
unittest . CheckConsistencyFor ( t , & repo_model . Repository { ID : milestone . RepoID } , & issues_model . Milestone { } )
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . ChangeMilestoneStatus ( db . DefaultContext , milestone , false ) )
2022-06-13 12:37:59 +03:00
unittest . AssertExistsAndLoadBean ( t , & issues_model . Milestone { ID : 1 } , "is_closed=0" )
unittest . CheckConsistencyFor ( t , & repo_model . Repository { ID : milestone . RepoID } , & issues_model . Milestone { } )
}
func TestDeleteMilestoneByRepoID ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . DeleteMilestoneByRepoID ( db . DefaultContext , 1 , 1 ) )
2022-06-13 12:37:59 +03:00
unittest . AssertNotExistsBean ( t , & issues_model . Milestone { ID : 1 } )
unittest . CheckConsistencyFor ( t , & repo_model . Repository { ID : 1 } )
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . DeleteMilestoneByRepoID ( db . DefaultContext , unittest . NonexistentID , unittest . NonexistentID ) )
2022-06-13 12:37:59 +03:00
}
func TestUpdateMilestone ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
2022-08-16 05:22:25 +03:00
milestone := unittest . AssertExistsAndLoadBean ( t , & issues_model . Milestone { ID : 1 } )
2022-06-13 12:37:59 +03:00
milestone . Name = " newMilestoneName "
milestone . Content = "newMilestoneContent"
2023-09-16 17:39:12 +03:00
assert . NoError ( t , issues_model . UpdateMilestone ( db . DefaultContext , milestone , milestone . IsClosed ) )
2022-08-16 05:22:25 +03:00
milestone = unittest . AssertExistsAndLoadBean ( t , & issues_model . Milestone { ID : 1 } )
2022-06-13 12:37:59 +03:00
assert . EqualValues ( t , "newMilestoneName" , milestone . Name )
unittest . CheckConsistencyFor ( t , & issues_model . Milestone { } )
}
func TestUpdateMilestoneCounters ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
issue := unittest . AssertExistsAndLoadBean ( t , & issues_model . Issue { MilestoneID : 1 } ,
2022-08-16 05:22:25 +03:00
"is_closed=0" )
2022-06-13 12:37:59 +03:00
issue . IsClosed = true
issue . ClosedUnix = timeutil . TimeStampNow ( )
_ , err := db . GetEngine ( db . DefaultContext ) . ID ( issue . ID ) . Cols ( "is_closed" , "closed_unix" ) . Update ( issue )
assert . NoError ( t , err )
assert . NoError ( t , issues_model . UpdateMilestoneCounters ( db . DefaultContext , issue . MilestoneID ) )
unittest . CheckConsistencyFor ( t , & issues_model . Milestone { } )
issue . IsClosed = false
issue . ClosedUnix = 0
_ , err = db . GetEngine ( db . DefaultContext ) . ID ( issue . ID ) . Cols ( "is_closed" , "closed_unix" ) . Update ( issue )
assert . NoError ( t , err )
assert . NoError ( t , issues_model . UpdateMilestoneCounters ( db . DefaultContext , issue . MilestoneID ) )
unittest . CheckConsistencyFor ( t , & issues_model . Milestone { } )
}
2023-09-09 00:09:23 +03:00
func TestMigrate_InsertMilestones ( t * testing . T ) {
assert . NoError ( t , unittest . PrepareTestDatabase ( ) )
reponame := "repo1"
repo := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { Name : reponame } )
name := "milestonetest1"
ms := & issues_model . Milestone {
RepoID : repo . ID ,
Name : name ,
}
2023-09-16 17:39:12 +03:00
err := issues_model . InsertMilestones ( db . DefaultContext , ms )
2023-09-09 00:09:23 +03:00
assert . NoError ( t , err )
unittest . AssertExistsAndLoadBean ( t , ms )
repoModified := unittest . AssertExistsAndLoadBean ( t , & repo_model . Repository { ID : repo . ID } )
assert . EqualValues ( t , repo . NumMilestones + 1 , repoModified . NumMilestones )
unittest . CheckConsistencyFor ( t , & issues_model . Milestone { } )
}