mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-08 14:35:52 +01:00
Extend API to allow CRUD labels
Add Labels API
* List all labels for this repository
* Get a single label
* Create a label
* Update a label
* Delete a label
Reject duplicated label name
Add test case for LabelsService
This commit is contained in:
21
src/main/scala/gitbucket/core/api/ApiLabel.scala
Normal file
21
src/main/scala/gitbucket/core/api/ApiLabel.scala
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package gitbucket.core.api
|
||||||
|
|
||||||
|
import gitbucket.core.model.Label
|
||||||
|
import gitbucket.core.util.RepositoryName
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://developer.github.com/v3/issues/labels/
|
||||||
|
*/
|
||||||
|
case class ApiLabel(
|
||||||
|
name: String,
|
||||||
|
color: String)(repositoryName: RepositoryName){
|
||||||
|
var url = ApiPath(s"/api/v3/repos/${repositoryName.fullName}/labels/${name}")
|
||||||
|
}
|
||||||
|
|
||||||
|
object ApiLabel{
|
||||||
|
def apply(label:Label, repositoryName: RepositoryName): ApiLabel =
|
||||||
|
ApiLabel(
|
||||||
|
name = label.labelName,
|
||||||
|
color = label.color
|
||||||
|
)(repositoryName)
|
||||||
|
}
|
||||||
18
src/main/scala/gitbucket/core/api/CreateALabel.scala
Normal file
18
src/main/scala/gitbucket/core/api/CreateALabel.scala
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package gitbucket.core.api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* https://developer.github.com/v3/issues/labels/#create-a-label
|
||||||
|
* api form
|
||||||
|
*/
|
||||||
|
case class CreateALabel(
|
||||||
|
name: String,
|
||||||
|
color: String
|
||||||
|
) {
|
||||||
|
def isValid: Boolean = {
|
||||||
|
name.length<=100 &&
|
||||||
|
!name.startsWith("_") &&
|
||||||
|
!name.startsWith("-") &&
|
||||||
|
color.length==6 &&
|
||||||
|
color.matches("[a-fA-F0-9+_.]+")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ object JsonFormat {
|
|||||||
FieldSerializer[ApiPullRequest.Commit]() +
|
FieldSerializer[ApiPullRequest.Commit]() +
|
||||||
FieldSerializer[ApiIssue]() +
|
FieldSerializer[ApiIssue]() +
|
||||||
FieldSerializer[ApiComment]() +
|
FieldSerializer[ApiComment]() +
|
||||||
|
FieldSerializer[ApiLabel]() +
|
||||||
ApiBranchProtection.enforcementLevelSerializer
|
ApiBranchProtection.enforcementLevelSerializer
|
||||||
|
|
||||||
def apiPathSerializer(c: Context) = new CustomSerializer[ApiPath](format =>
|
def apiPathSerializer(c: Context) = new CustomSerializer[ApiPath](format =>
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
package gitbucket.core.controller
|
package gitbucket.core.controller
|
||||||
|
|
||||||
|
import gitbucket.core.api.{ApiError, CreateALabel, ApiLabel, JsonFormat}
|
||||||
import gitbucket.core.issues.labels.html
|
import gitbucket.core.issues.labels.html
|
||||||
import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService}
|
import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, LabelsService}
|
||||||
import gitbucket.core.util.{ReferrerAuthenticator, CollaboratorsAuthenticator}
|
import gitbucket.core.util.{LockUtil, RepositoryName, ReferrerAuthenticator, CollaboratorsAuthenticator}
|
||||||
import gitbucket.core.util.Implicits._
|
import gitbucket.core.util.Implicits._
|
||||||
import io.github.gitbucket.scalatra.forms._
|
import io.github.gitbucket.scalatra.forms._
|
||||||
import org.scalatra.i18n.Messages
|
import org.scalatra.i18n.Messages
|
||||||
import org.scalatra.Ok
|
import org.scalatra.{UnprocessableEntity, Created, Ok}
|
||||||
|
|
||||||
class LabelsController extends LabelsControllerBase
|
class LabelsController extends LabelsControllerBase
|
||||||
with LabelsService with IssuesService with RepositoryService with AccountService
|
with LabelsService with IssuesService with RepositoryService with AccountService
|
||||||
@@ -19,7 +20,7 @@ trait LabelsControllerBase extends ControllerBase {
|
|||||||
case class LabelForm(labelName: String, color: String)
|
case class LabelForm(labelName: String, color: String)
|
||||||
|
|
||||||
val labelForm = mapping(
|
val labelForm = mapping(
|
||||||
"labelName" -> trim(label("Label name", text(required, labelName, maxlength(100)))),
|
"labelName" -> trim(label("Label name", text(required, labelName, uniqueLabelName, maxlength(100)))),
|
||||||
"labelColor" -> trim(label("Color", text(required, color)))
|
"labelColor" -> trim(label("Color", text(required, color)))
|
||||||
)(LabelForm.apply)
|
)(LabelForm.apply)
|
||||||
|
|
||||||
@@ -31,6 +32,26 @@ trait LabelsControllerBase extends ControllerBase {
|
|||||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all labels for this repository
|
||||||
|
* https://developer.github.com/v3/issues/labels/#list-all-labels-for-this-repository
|
||||||
|
*/
|
||||||
|
get("/api/v3/repos/:owner/:repository/labels")(referrersOnly { repository =>
|
||||||
|
getLabels(repository.owner, repository.name).map { label =>
|
||||||
|
JsonFormat(ApiLabel(label, RepositoryName(repository)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a single label
|
||||||
|
* https://developer.github.com/v3/issues/labels/#get-a-single-label
|
||||||
|
*/
|
||||||
|
get("/api/v3/repos/:owner/:repository/labels/:labelName")(referrersOnly { repository =>
|
||||||
|
getLabel(repository.owner, repository.name, params("labelName")).map { label =>
|
||||||
|
JsonFormat(ApiLabel(label, RepositoryName(repository)))
|
||||||
|
} getOrElse NotFound()
|
||||||
|
})
|
||||||
|
|
||||||
ajaxGet("/:owner/:repository/issues/labels/new")(collaboratorsOnly { repository =>
|
ajaxGet("/:owner/:repository/issues/labels/new")(collaboratorsOnly { repository =>
|
||||||
html.edit(None, repository)
|
html.edit(None, repository)
|
||||||
})
|
})
|
||||||
@@ -45,6 +66,31 @@ trait LabelsControllerBase extends ControllerBase {
|
|||||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a label
|
||||||
|
* https://developer.github.com/v3/issues/labels/#create-a-label
|
||||||
|
*/
|
||||||
|
post("/api/v3/repos/:owner/:repository/labels")(collaboratorsOnly { repository =>
|
||||||
|
(for{
|
||||||
|
data <- extractFromJsonBody[CreateALabel] if data.isValid
|
||||||
|
} yield {
|
||||||
|
LockUtil.lock(RepositoryName(repository).fullName) {
|
||||||
|
if (getLabel(repository.owner, repository.name, data.name).isEmpty) {
|
||||||
|
val labelId = createLabel(repository.owner, repository.name, data.name, data.color)
|
||||||
|
getLabel(repository.owner, repository.name, labelId).map { label =>
|
||||||
|
Created(JsonFormat(ApiLabel(label, RepositoryName(repository))))
|
||||||
|
} getOrElse NotFound()
|
||||||
|
} else {
|
||||||
|
// TODO ApiError should support errors field to enhance compatibility of GitHub API
|
||||||
|
UnprocessableEntity(ApiError(
|
||||||
|
"Validation Failed",
|
||||||
|
Some("https://developer.github.com/v3/issues/labels/#create-a-label")
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) getOrElse NotFound()
|
||||||
|
})
|
||||||
|
|
||||||
ajaxGet("/:owner/:repository/issues/labels/:labelId/edit")(collaboratorsOnly { repository =>
|
ajaxGet("/:owner/:repository/issues/labels/:labelId/edit")(collaboratorsOnly { repository =>
|
||||||
getLabel(repository.owner, repository.name, params("labelId").toInt).map { label =>
|
getLabel(repository.owner, repository.name, params("labelId").toInt).map { label =>
|
||||||
html.edit(Some(label), repository)
|
html.edit(Some(label), repository)
|
||||||
@@ -61,11 +107,50 @@ trait LabelsControllerBase extends ControllerBase {
|
|||||||
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
hasWritePermission(repository.owner, repository.name, context.loginAccount))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a label
|
||||||
|
* https://developer.github.com/v3/issues/labels/#update-a-label
|
||||||
|
*/
|
||||||
|
patch("/api/v3/repos/:owner/:repository/labels/:labelName")(collaboratorsOnly { repository =>
|
||||||
|
(for{
|
||||||
|
data <- extractFromJsonBody[CreateALabel] if data.isValid
|
||||||
|
} yield {
|
||||||
|
LockUtil.lock(RepositoryName(repository).fullName) {
|
||||||
|
getLabel(repository.owner, repository.name, params("labelName")).map { label =>
|
||||||
|
if (getLabel(repository.owner, repository.name, data.name).isEmpty) {
|
||||||
|
updateLabel(repository.owner, repository.name, label.labelId, data.name, data.color)
|
||||||
|
JsonFormat(ApiLabel(
|
||||||
|
getLabel(repository.owner, repository.name, label.labelId).get,
|
||||||
|
RepositoryName(repository)))
|
||||||
|
} else {
|
||||||
|
// TODO ApiError should support errors field to enhance compatibility of GitHub API
|
||||||
|
UnprocessableEntity(ApiError(
|
||||||
|
"Validation Failed",
|
||||||
|
Some("https://developer.github.com/v3/issues/labels/#create-a-label")))
|
||||||
|
}
|
||||||
|
} getOrElse NotFound()
|
||||||
|
}
|
||||||
|
}) getOrElse NotFound()
|
||||||
|
})
|
||||||
|
|
||||||
ajaxPost("/:owner/:repository/issues/labels/:labelId/delete")(collaboratorsOnly { repository =>
|
ajaxPost("/:owner/:repository/issues/labels/:labelId/delete")(collaboratorsOnly { repository =>
|
||||||
deleteLabel(repository.owner, repository.name, params("labelId").toInt)
|
deleteLabel(repository.owner, repository.name, params("labelId").toInt)
|
||||||
Ok()
|
Ok()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a label
|
||||||
|
* https://developer.github.com/v3/issues/labels/#delete-a-label
|
||||||
|
*/
|
||||||
|
delete("/api/v3/repos/:owner/:repository/labels/:labelName")(collaboratorsOnly { repository =>
|
||||||
|
LockUtil.lock(RepositoryName(repository).fullName) {
|
||||||
|
getLabel(repository.owner, repository.name, params("labelName")).map { label =>
|
||||||
|
deleteLabel(repository.owner, repository.name, label.labelId)
|
||||||
|
Ok()
|
||||||
|
} getOrElse NotFound()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constraint for the identifier such as user name, repository name or page name.
|
* Constraint for the identifier such as user name, repository name or page name.
|
||||||
*/
|
*/
|
||||||
@@ -80,4 +165,12 @@ trait LabelsControllerBase extends ControllerBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private def uniqueLabelName: Constraint = new Constraint(){
|
||||||
|
override def validate(name: String, value: String, params: Map[String, String], messages: Messages): Option[String] = {
|
||||||
|
val owner = params("owner")
|
||||||
|
val repository = params("repository")
|
||||||
|
getLabel(owner, repository, value).map(_ => "Name has already been taken.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,16 @@ protected[model] trait TemplateComponent { self: Profile =>
|
|||||||
|
|
||||||
trait LabelTemplate extends BasicTemplate { self: Table[_] =>
|
trait LabelTemplate extends BasicTemplate { self: Table[_] =>
|
||||||
val labelId = column[Int]("LABEL_ID")
|
val labelId = column[Int]("LABEL_ID")
|
||||||
|
val labelName = column[String]("LABEL_NAME")
|
||||||
|
|
||||||
def byLabel(owner: String, repository: String, labelId: Int) =
|
def byLabel(owner: String, repository: String, labelId: Int) =
|
||||||
byRepository(owner, repository) && (this.labelId === labelId.bind)
|
byRepository(owner, repository) && (this.labelId === labelId.bind)
|
||||||
|
|
||||||
def byLabel(userName: Column[String], repositoryName: Column[String], labelId: Column[Int]) =
|
def byLabel(userName: Column[String], repositoryName: Column[String], labelId: Column[Int]) =
|
||||||
byRepository(userName, repositoryName) && (this.labelId === labelId)
|
byRepository(userName, repositoryName) && (this.labelId === labelId)
|
||||||
|
|
||||||
|
def byLabel(owner: String, repository: String, labelName: String) =
|
||||||
|
byRepository(userName, repositoryName) && (this.labelName === labelName.bind)
|
||||||
}
|
}
|
||||||
|
|
||||||
trait MilestoneTemplate extends BasicTemplate { self: Table[_] =>
|
trait MilestoneTemplate extends BasicTemplate { self: Table[_] =>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ trait LabelComponent extends TemplateComponent { self: Profile =>
|
|||||||
|
|
||||||
class Labels(tag: Tag) extends Table[Label](tag, "LABEL") with LabelTemplate {
|
class Labels(tag: Tag) extends Table[Label](tag, "LABEL") with LabelTemplate {
|
||||||
override val labelId = column[Int]("LABEL_ID", O AutoInc)
|
override val labelId = column[Int]("LABEL_ID", O AutoInc)
|
||||||
val labelName = column[String]("LABEL_NAME")
|
override val labelName = column[String]("LABEL_NAME")
|
||||||
val color = column[String]("COLOR")
|
val color = column[String]("COLOR")
|
||||||
def * = (userName, repositoryName, labelId, labelName, color) <> (Label.tupled, Label.unapply)
|
def * = (userName, repositoryName, labelId, labelName, color) <> (Label.tupled, Label.unapply)
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ trait LabelsService {
|
|||||||
def getLabel(owner: String, repository: String, labelId: Int)(implicit s: Session): Option[Label] =
|
def getLabel(owner: String, repository: String, labelId: Int)(implicit s: Session): Option[Label] =
|
||||||
Labels.filter(_.byPrimaryKey(owner, repository, labelId)).firstOption
|
Labels.filter(_.byPrimaryKey(owner, repository, labelId)).firstOption
|
||||||
|
|
||||||
|
def getLabel(owner: String, repository: String, labelName: String)(implicit s: Session): Option[Label] =
|
||||||
|
Labels.filter(_.byLabel(owner, repository, labelName)).firstOption
|
||||||
|
|
||||||
def createLabel(owner: String, repository: String, labelName: String, color: String)(implicit s: Session): Int =
|
def createLabel(owner: String, repository: String, labelName: String, color: String)(implicit s: Session): Int =
|
||||||
Labels returning Labels.map(_.labelId) += Label(
|
Labels returning Labels.map(_.labelId) += Label(
|
||||||
userName = owner,
|
userName = owner,
|
||||||
|
|||||||
@@ -209,6 +209,15 @@ class JsonFormatSpec extends Specification {
|
|||||||
"url": "${context.baseUrl}/api/v3/repos/octocat/Hello-World/commits/$sha1/status"
|
"url": "${context.baseUrl}/api/v3/repos/octocat/Hello-World/commits/$sha1/status"
|
||||||
}"""
|
}"""
|
||||||
|
|
||||||
|
val apiLabel = ApiLabel(
|
||||||
|
name = "bug",
|
||||||
|
color = "f29513")(RepositoryName("octocat","Hello-World"))
|
||||||
|
val apiLabelJson = s"""{
|
||||||
|
"name": "bug",
|
||||||
|
"color": "f29513",
|
||||||
|
"url": "${context.baseUrl}/api/v3/repos/octocat/Hello-World/labels/bug"
|
||||||
|
}"""
|
||||||
|
|
||||||
val apiIssue = ApiIssue(
|
val apiIssue = ApiIssue(
|
||||||
number = 1347,
|
number = 1347,
|
||||||
title = "Found a bug",
|
title = "Found a bug",
|
||||||
@@ -411,6 +420,9 @@ class JsonFormatSpec extends Specification {
|
|||||||
"apiCombinedCommitStatus" in {
|
"apiCombinedCommitStatus" in {
|
||||||
JsonFormat(apiCombinedCommitStatus) must beFormatted(apiCombinedCommitStatusJson)
|
JsonFormat(apiCombinedCommitStatus) must beFormatted(apiCombinedCommitStatusJson)
|
||||||
}
|
}
|
||||||
|
"apiLabel" in {
|
||||||
|
JsonFormat(apiLabel) must beFormatted(apiLabelJson)
|
||||||
|
}
|
||||||
"apiIssue" in {
|
"apiIssue" in {
|
||||||
JsonFormat(apiIssue) must beFormatted(apiIssueJson)
|
JsonFormat(apiIssue) must beFormatted(apiIssueJson)
|
||||||
JsonFormat(apiIssuePR) must beFormatted(apiIssuePRJson)
|
JsonFormat(apiIssuePR) must beFormatted(apiIssuePRJson)
|
||||||
|
|||||||
114
src/test/scala/gitbucket/core/service/LabelsServiceSpec.scala
Normal file
114
src/test/scala/gitbucket/core/service/LabelsServiceSpec.scala
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package gitbucket.core.service
|
||||||
|
|
||||||
|
import gitbucket.core.model._
|
||||||
|
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
class LabelsServiceSpec extends Specification with ServiceSpecBase {
|
||||||
|
"getLabels" should {
|
||||||
|
"be empty when not have any labels" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
|
||||||
|
dummyService.getLabels("user1", "repo1") must haveSize(0)
|
||||||
|
}}
|
||||||
|
"return contained labels" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
val labelId1 = dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
val labelId2 = dummyService.createLabel("user1", "repo1", "label2", "ffffff")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
|
||||||
|
def getLabels = dummyService.getLabels("user1", "repo1")
|
||||||
|
|
||||||
|
getLabels must haveSize(2)
|
||||||
|
getLabels must_== List(
|
||||||
|
Label("user1", "repo1", labelId1, "label1", "000000"),
|
||||||
|
Label("user1", "repo1", labelId2, "label2", "ffffff"))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
"getLabel" should {
|
||||||
|
"return None when the label not exist" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
|
||||||
|
dummyService.getLabel("user1", "repo1", 1) must beNone
|
||||||
|
dummyService.getLabel("user1", "repo1", "label1") must beNone
|
||||||
|
}}
|
||||||
|
"return a label fetched by label id" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
val labelId1 = dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
dummyService.createLabel("user1", "repo1", "label2", "ffffff")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
|
||||||
|
def getLabel = dummyService.getLabel("user1", "repo1", labelId1)
|
||||||
|
getLabel must_== Some(Label("user1", "repo1", labelId1, "label1", "000000"))
|
||||||
|
}}
|
||||||
|
"return a label fetched by label name" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
val labelId1 = dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
dummyService.createLabel("user1", "repo1", "label2", "ffffff")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
|
||||||
|
def getLabel = dummyService.getLabel("user1", "repo1", "label1")
|
||||||
|
getLabel must_== Some(Label("user1", "repo1", labelId1, "label1", "000000"))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
"createLabel" should {
|
||||||
|
"return accurate label id" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
val labelId = dummyService.createLabel("user1", "repo1", "label2", "000000")
|
||||||
|
labelId must_== 4
|
||||||
|
def getLabel = dummyService.getLabel("user1", "repo1", labelId)
|
||||||
|
getLabel must_== Some(Label("user1", "repo1", labelId, "label2", "000000"))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
"updateLabel" should {
|
||||||
|
"change target label" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
val labelId = dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
dummyService.updateLabel("user1", "repo1", labelId, "updated-label", "ffffff")
|
||||||
|
def getLabel = dummyService.getLabel("user1", "repo1", labelId)
|
||||||
|
getLabel must_== Some(Label("user1", "repo1", labelId, "updated-label", "ffffff"))
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
"deleteLabel" should {
|
||||||
|
"remove target label" in { withTestDB { implicit session =>
|
||||||
|
generateNewUserWithDBRepository("user1", "repo1")
|
||||||
|
generateNewUserWithDBRepository("user1", "repo2")
|
||||||
|
generateNewUserWithDBRepository("user2", "repo1")
|
||||||
|
val labelId = dummyService.createLabel("user1", "repo1", "label1", "000000")
|
||||||
|
dummyService.createLabel("user1", "repo2", "label1", "000000")
|
||||||
|
dummyService.createLabel("user2", "repo1", "label1", "000000")
|
||||||
|
dummyService.deleteLabel("user1", "repo1", labelId)
|
||||||
|
dummyService.getLabel("user1", "repo1", labelId) must beNone
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ trait ServiceSpecBase {
|
|||||||
def user(name:String)(implicit s:Session):Account = AccountService.getAccountByUserName(name).get
|
def user(name:String)(implicit s:Session):Account = AccountService.getAccountByUserName(name).get
|
||||||
|
|
||||||
lazy val dummyService = new RepositoryService with AccountService with IssuesService with PullRequestService
|
lazy val dummyService = new RepositoryService with AccountService with IssuesService with PullRequestService
|
||||||
with CommitStatusService (){}
|
with CommitStatusService with LabelsService (){}
|
||||||
|
|
||||||
def generateNewUserWithDBRepository(userName:String, repositoryName:String)(implicit s:Session):Account = {
|
def generateNewUserWithDBRepository(userName:String, repositoryName:String)(implicit s:Session):Account = {
|
||||||
val ac = AccountService.getAccountByUserName(userName).getOrElse(generateNewAccount(userName))
|
val ac = AccountService.getAccountByUserName(userName).getOrElse(generateNewAccount(userName))
|
||||||
|
|||||||
Reference in New Issue
Block a user