...
 
Commits (26)
......@@ -3,24 +3,20 @@ package ru.terrakok.gitlabclient.entity.app.target
/**
* Created by Konstantin Tskhovrebov (aka @terrakok) on 26.12.17.
*/
sealed class TargetBadge(
val target: AppTarget?,
val targetId: Long?,
val internal: TargetInternal?
) {
class Text(
val text: String,
target: AppTarget? = null,
targetId: Long? = null,
internal: TargetInternal? = null
) : TargetBadge(target, targetId, internal)
sealed class TargetBadge {
data class Text(
val text: String,
val target: AppTarget? = null,
val targetId: Long? = null,
val internal: TargetInternal? = null
) : TargetBadge()
class Icon(
val icon: TargetBadgeIcon,
val count: Int
) : TargetBadge(null, null, null)
data class Icon(
val icon: TargetBadgeIcon,
val count: Int
) : TargetBadge()
class Status(
val status: TargetBadgeStatus
) : TargetBadge(null, null, null)
data class Status(
val status: TargetBadgeStatus
) : TargetBadge()
}
\ No newline at end of file
......@@ -2,8 +2,6 @@ package ru.terrakok.gitlabclient
import org.junit.Assert
import org.junit.Test
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.Visibility
import ru.terrakok.gitlabclient.model.data.server.MarkDownUrlResolver
/**
......@@ -12,12 +10,7 @@ import ru.terrakok.gitlabclient.model.data.server.MarkDownUrlResolver
class MarkDownUrlResolverTest {
private val markDownUrlResolver = MarkDownUrlResolver()
private val project = Project(
1, null, "", Visibility.PUBLIC, "", "", "", null, null, "GitFox", "", "",
"terrakok/gitlab-client", true, 1, true, true, true, true, true, null, null, 1, null, null, false, null, true,
1, 1, null, true, null, true, true, true, null
)
private val project = TestData.getProject(1)
@Test
fun check_markdown_without_image() {
......
package ru.terrakok.gitlabclient
import com.google.gson.GsonBuilder
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month
import ru.terrakok.gitlabclient.entity.*
import ru.terrakok.gitlabclient.entity.app.session.UserAccount
import ru.terrakok.gitlabclient.entity.app.target.*
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.event.EventTargetType
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequest
import ru.terrakok.gitlabclient.entity.mergerequest.MergeRequestState
import ru.terrakok.gitlabclient.entity.milestone.Milestone
import ru.terrakok.gitlabclient.entity.milestone.MilestoneState
import ru.terrakok.gitlabclient.entity.target.TargetState
import ru.terrakok.gitlabclient.entity.target.TargetType
import ru.terrakok.gitlabclient.entity.todo.Todo
import ru.terrakok.gitlabclient.entity.todo.TodoAction
import ru.terrakok.gitlabclient.model.data.server.deserializer.LocalDateTimeDeserializer
import ru.terrakok.gitlabclient.model.data.server.deserializer.TodoDeserializer
/**
* @author Vitaliy Belyaev on 01.06.2019.
*/
object TestData {
val todoJson =
"""
{
"id": 102,
"project": {
"id": 2,
"name": "Gitlab Ce",
"name_with_namespace": "Gitlab Org / Gitlab Ce",
"path": "gitlab-ce",
"path_with_namespace": "gitlab-org/gitlab-ce"
},
"author": {
"name": "Administrator",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "https://gitlab.example.com/root"
},
"action_name": "marked",
"target_type": "MergeRequest",
"target": {
"id": 34,
"iid": 7,
"project_id": 2,
"title": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",
"description": "Et ea et omnis illum cupiditate. Dolor aspernatur tenetur ducimus facilis est nihil. Quo esse cupiditate molestiae illo corrupti qui quidem dolor.",
"state": "opened",
"created_at": "2016-06-17T07:49:24.419Z",
"updated_at": "2016-06-17T07:52:43.484Z",
"target_branch": "tutorials_git_tricks",
"source_branch": "DNSBL_docs",
"upvotes": 0,
"downvotes": 0,
"author": {
"name": "Maxie Medhurst",
"username": "craig_rutherford",
"id": 12,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/a0d477b3ea21970ce6ffcbb817b0b435?s=80&d=identicon",
"web_url": "https://gitlab.example.com/craig_rutherford"
},
"assignee": {
"name": "Administrator",
"username": "root",
"id": 1,
"state": "active",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "https://gitlab.example.com/root"
},
"source_project_id": 2,
"target_project_id": 2,
"labels": [],
"work_in_progress": false,
"milestone": {
"id": 32,
"iid": 2,
"project_id": 2,
"title": "v1.0",
"description": "Assumenda placeat ea voluptatem voluptate qui.",
"state": "active",
"created_at": "2016-06-17T07:47:34.163Z",
"updated_at": "2016-06-17T07:47:34.163Z",
"due_date": null
},
"merge_when_pipeline_succeeds": false,
"merge_status": "cannot_be_merged",
"subscribed": true,
"user_notes_count": 7
},
"target_url": "https://gitlab.example.com/gitlab-org/gitlab-ce/merge_requests/7",
"body": "Dolores in voluptatem tenetur praesentium omnis repellendus voluptatem quaerat.",
"state": "pending",
"created_at": "2016-06-17T07:52:35.225Z"
}
"""
fun getCommit() = Commit(
"dsf233fef2fes34",
"dsf233",
"commit title",
"Mr Maintainer",
null,
LocalDateTime.of(2007, Month.JULY, 14, 11, 0),
null,
null,
null,
LocalDateTime.of(2007, Month.JUNE, 23, 11, 0),
"commit message",
listOf("wqdwqe23s3e", "fesfesf232")
)
fun getNote() = Note(
13L,
"note test body",
Author(11L, "state", "url", "name", "avatar", "username"),
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
null,
false,
435L,
EventTargetType.ISSUE,
333L)
fun getProject(projectId: Long) = Project(
id = projectId,
description = null,
defaultBranch = "test_br",
visibility = Visibility.PUBLIC,
sshUrlToRepo = null,
httpUrlToRepo = null,
webUrl = "https://gitlab.com/terrakok/gitlab-client",
tagList = null,
owner = null,
name = "GitFox",
nameWithNamespace = "",
path = "test path",
pathWithNamespace = "terrakok/gitlab-client",
issuesEnabled = false,
openIssuesCount = 0L,
mergeRequestsEnabled = false,
jobsEnabled = false,
wikiEnabled = false,
snippetsEnabled = false,
containerRegistryEnabled = false,
createdAt = null,
lastActivityAt = null,
creatorId = 0L,
namespace = null,
permissions = null,
archived = false,
avatarUrl = null,
sharedRunnersEnabled = false,
forksCount = 0L,
starCount = 0L,
runnersToken = null,
publicJobs = false,
sharedWithGroups = null,
onlyAllowMergeIfPipelineSucceeds = false,
onlyAllowMergeIfAllDiscussionsAreResolved = false,
requestAccessEnabled = false,
readmeUrl = "https://gitlab.com/terrakok/gitlab-client/blob/test_br/README.md"
)
fun getMergeRequest() = MergeRequest(
321123L,
5555L,
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
null,
"target branch",
"source branch",
9999L,
"MR title",
MergeRequestState.OPENED,
2,
1,
Author(11L, "state", "url", "name", "avatar", "username"),
null,
8888,
7777,
"description",
false,
null,
true,
null,
"sha",
null,
3,
true,
false,
null,
null,
listOf("label 1", "label 2"),
null,
null,
null,
null,
null
)
fun getExpectedTargetHeader(mr: MergeRequest, project: Project): TargetHeader {
val badges = mutableListOf<TargetBadge>()
badges.add(
TargetBadge.Status(
when (mr.state) {
MergeRequestState.OPENED -> TargetBadgeStatus.OPENED
MergeRequestState.CLOSED -> TargetBadgeStatus.CLOSED
MergeRequestState.MERGED -> TargetBadgeStatus.MERGED
}
)
)
badges.add(TargetBadge.Text(project.name, AppTarget.PROJECT, project.id))
badges.add(TargetBadge.Text(mr.author.username, AppTarget.USER, mr.author.id))
badges.add(TargetBadge.Icon(TargetBadgeIcon.COMMENTS, mr.userNotesCount))
badges.add(TargetBadge.Icon(TargetBadgeIcon.UP_VOTES, mr.upvotes))
badges.add(TargetBadge.Icon(TargetBadgeIcon.DOWN_VOTES, mr.downvotes))
mr.labels.forEach { label -> badges.add(TargetBadge.Text(label)) }
return TargetHeader.Public(
mr.author,
TargetHeaderIcon.NONE,
TargetHeaderTitle.Event(
mr.author.name,
EventAction.CREATED,
"${AppTarget.MERGE_REQUEST} !${mr.iid}",
project.name
),
mr.title ?: "",
mr.createdAt,
AppTarget.MERGE_REQUEST,
mr.id,
TargetInternal(mr.projectId, mr.iid),
badges,
TargetAction.Undefined
)
}
fun getFile(content: String = "file content", branch: String = "test_br") = File(
"file name",
"file path",
500L,
"encoding",
content,
branch,
"blob id",
"commit id",
"last commit id"
)
fun getRepositoryTreeNode() = RepositoryTreeNode(
"some id",
"some name",
RepositoryTreeNodeType.TREE,
"some path",
"mode"
)
fun getBranch() = Branch(
"some name",
merged = false,
protected = false,
default = true,
developersCanPush = true,
developersCanMerge = true,
canPush = false)
fun getMilestone() = Milestone(
123L,
321L,
333L,
"milestone description",
MilestoneState.ACTIVE,
null,
null,
null,
"milestone title",
null,
"url of milestone"
)
fun getLabel(id: Long = 555L, subscribed: Boolean = false) = Label(
id = id,
name = "name$id",
color = Color("green", 12),
description = "description",
openIssuesCount = 0,
closedIssuesCount = 0,
openMergeRequestsCount = 0,
subscribed = subscribed,
priority = null
)
fun getUserAccount() = UserAccount(
13L,
"token",
"user_server_path",
"user_avatar_url",
"user_name",
true
)
fun getTodo() = GsonBuilder()
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeDeserializer())
.registerTypeAdapter(Todo::class.java, TodoDeserializer())
.create().fromJson(todoJson, Todo::class.java)
fun getUser() = User(
4321L, "username", "email@mail.com", "Name", null,
null, null,
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
false, null, null, null, null, null,
null, null,
LocalDateTime.of(2009, Month.DECEMBER, 14, 11, 0),
LocalDateTime.of(2008, Month.DECEMBER, 14, 11, 0),
2424L, 32L,
LocalDateTime.of(2008, Month.DECEMBER, 14, 11, 0),
null, canCreateGroup = false, canCreateProject = false,
twoFactorEnabled = true, external = false
)
fun getTargetHeaderForTodo(todo: Todo, currentUser: User): TargetHeader {
val target = todo.target
val assignee = if (todo.actionName != TodoAction.MARKED) {
currentUser.let {
Assignee(it.id, it.state, it.name, it.webUrl, it.avatarUrl, it.username)
}
} else {
null
}
val appTarget = when (todo.targetType) {
TargetType.MERGE_REQUEST -> AppTarget.MERGE_REQUEST
TargetType.ISSUE -> AppTarget.ISSUE
}
val targetName = when (todo.targetType) {
TargetType.MERGE_REQUEST -> "${AppTarget.MERGE_REQUEST} !${target.iid}"
TargetType.ISSUE -> "${AppTarget.ISSUE} #${target.iid}"
}
val badges = mutableListOf<TargetBadge>()
badges.add(
TargetBadge.Status(
when (target.state) {
TargetState.OPENED -> TargetBadgeStatus.OPENED
TargetState.CLOSED -> TargetBadgeStatus.CLOSED
TargetState.MERGED -> TargetBadgeStatus.MERGED
}
)
)
badges.add(TargetBadge.Text(todo.author.username, AppTarget.USER, todo.author.id))
badges.add(TargetBadge.Text(todo.project.name, AppTarget.PROJECT, todo.project.id))
return TargetHeader.Public(
todo.author,
TargetHeaderIcon.NONE,
TargetHeaderTitle.Todo(
todo.author.name,
assignee?.name,
todo.actionName,
targetName,
todo.project.nameWithNamespace,
todo.author.id == currentUser.id,
assignee?.id == currentUser.id
),
todo.body,
todo.createdAt,
appTarget,
target.id,
TargetInternal(target.projectId, target.iid),
badges,
TargetAction.Undefined
)
}
}
\ No newline at end of file
......@@ -4,8 +4,11 @@ import io.reactivex.Single
import io.reactivex.observers.TestObserver
import org.junit.Test
import org.mockito.Mockito.*
import ru.terrakok.gitlabclient.TestData
import ru.terrakok.gitlabclient.TestSchedulers
import ru.terrakok.gitlabclient.entity.*
import ru.terrakok.gitlabclient.entity.Branch
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.RepositoryTreeNodeType
import ru.terrakok.gitlabclient.entity.app.ProjectFile
import ru.terrakok.gitlabclient.model.repository.project.ProjectRepository
import ru.terrakok.gitlabclient.model.repository.tools.Base64Tools
......@@ -23,45 +26,7 @@ class ProjectInteractorTest {
private val testError = RuntimeException("test error")
private val testPage = 13
private val testProject = Project(
id = 42L,
description = null,
defaultBranch = "test_br",
visibility = Visibility.PUBLIC,
sshUrlToRepo = null,
httpUrlToRepo = null,
webUrl = "https://gitlab.com/terrakok/gitlab-client",
tagList = null,
owner = null,
name = "",
nameWithNamespace = "",
path = "test path",
pathWithNamespace = "",
issuesEnabled = false,
openIssuesCount = 0L,
mergeRequestsEnabled = false,
jobsEnabled = false,
wikiEnabled = false,
snippetsEnabled = false,
containerRegistryEnabled = false,
createdAt = null,
lastActivityAt = null,
creatorId = 0L,
namespace = null,
permissions = null,
archived = false,
avatarUrl = null,
sharedRunnersEnabled = false,
forksCount = 0L,
starCount = 0L,
runnersToken = null,
publicJobs = false,
sharedWithGroups = null,
onlyAllowMergeIfPipelineSucceeds = false,
onlyAllowMergeIfAllDiscussionsAreResolved = false,
requestAccessEnabled = false,
readmeUrl = "https://gitlab.com/terrakok/gitlab-client/blob/test_br/README.md"
)
private val testProject = TestData.getProject(42L)
private val testProjectsList = listOf(testProject)
@Test
......@@ -185,16 +150,7 @@ class ProjectInteractorTest {
fun get_project_raw_file() {
val raw = "lorem ipsum"
val testFileContent = "bG9yZW0gaXBzdW0=" //base64 for raw
val testFile = File(
"",
"",
0L,
"",
testFileContent,
testProject.defaultBranch!!,
"",
"",
"")
val testFile = TestData.getFile(testFileContent, testProject.defaultBranch!!)
`when`(repo.getProjectFile(anyLong(), anyString(), anyString())).thenReturn(Single.just(testFile))
`when`(base64Tools.decode(anyString())).thenReturn(raw)
......@@ -217,16 +173,7 @@ class ProjectInteractorTest {
fun get_project_readme() {
val raw = "lorem ipsum"
val testFileContent = "bG9yZW0gaXBzdW0=" //base64 for raw
val testFile = File(
"",
"",
0L,
"",
testFileContent,
testProject.defaultBranch!!,
"",
"",
"")
val testFile =TestData.getFile(testFileContent, testProject.defaultBranch!!)
`when`(repo.getProjectFile(anyLong(), anyString(), anyString())).thenReturn(Single.just(testFile))
`when`(base64Tools.decode(anyString())).thenReturn(raw)
......
......@@ -9,8 +9,8 @@ import org.junit.Test
import org.mockito.ArgumentMatchers
import org.mockito.Mockito.`when`
import org.mockito.Mockito.verify
import ru.terrakok.gitlabclient.TestData
import ru.terrakok.gitlabclient.entity.app.session.OAuthParams
import ru.terrakok.gitlabclient.entity.app.session.UserAccount
import ru.terrakok.gitlabclient.model.data.cache.ProjectCache
import ru.terrakok.gitlabclient.model.repository.session.SessionRepository
......@@ -29,14 +29,8 @@ class SessionInteractorTest {
private val OAUTH_PARAMS =
OAuthParams("appId", "appKey", "redirect_url")
private val testAccount = UserAccount(
13L,
"token",
"user_server_path",
"user_avatar_url",
"user_name",
true)
private val testAccount = TestData.getUserAccount()
@Before
fun setUp() {
repository = mock()
......
package ru.terrakok.gitlabclient.model.repository.app
import io.reactivex.Single
import org.junit.Assert.assertEquals
import org.junit.Test
import org.mockito.Mockito.*
import ru.terrakok.gitlabclient.TestSchedulers
import ru.terrakok.gitlabclient.entity.app.develop.AppInfo
import ru.terrakok.gitlabclient.entity.app.develop.AppLibrary
import ru.terrakok.gitlabclient.entity.app.develop.LicenseType
import ru.terrakok.gitlabclient.model.data.storage.Prefs
import ru.terrakok.gitlabclient.model.data.storage.RawAppData
/**
* @author Vitaliy Belyaev on 21.05.2019.
*/
class AppInfoRepositoryTest {
private val appInfo = AppInfo(
"1.5.1",
13,
"test description",
"wer342frvr3",
"https://gitlab.com/terrakok/gitlab-client",
"https://gitlab.com/terrakok/gitlab-client/issues"
)
private val testAppLibraries = listOf(AppLibrary("name", "url", LicenseType.MIT))
private val rawAppData = mock(RawAppData::class.java)
private val prefs = mock(Prefs::class.java)
private val repository = AppInfoRepository(rawAppData, appInfo, prefs, TestSchedulers())
@Test
fun `get timestamp success`() {
val timestamp = 1234545454L
`when`(prefs.firstLaunchTimeStamp).thenReturn(timestamp)
val result = repository.firstLaunchTimeStamp
verify(prefs, times(1)).firstLaunchTimeStamp
verifyNoMoreInteractions(prefs)
assertEquals(timestamp, result)
}
@Test
fun `set timestamp success`() {
val timestamp = 1234545454L
repository.firstLaunchTimeStamp = timestamp
verify(prefs, times(1)).firstLaunchTimeStamp = timestamp
verifyNoMoreInteractions(prefs)
}
@Test
fun `get app info success`() {
val testObserver = repository.getAppInfo().test()
testObserver
.assertNoErrors()
.assertValue(appInfo)
.assertComplete()
}
@Test
fun `get app libraries success`() {
`when`(rawAppData.getAppLibraries()).thenReturn(Single.just(testAppLibraries))
val testObserver = repository.getAppLibraries().test()
verify(rawAppData, times(1)).getAppLibraries()
verifyNoMoreInteractions(rawAppData)
testObserver
.assertNoErrors()
.assertValue(testAppLibraries)
.assertComplete()
}
@Test
fun `get empty libraries list on error`() {
`when`(rawAppData.getAppLibraries()).thenReturn(Single.error(RuntimeException()))
val testObserver = repository.getAppLibraries().test()
verify(rawAppData, times(1)).getAppLibraries()
verifyNoMoreInteractions(rawAppData)
testObserver
.assertNoErrors()
.assertValue(emptyList())
.assertComplete()
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.repository.event
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.anyOrNull
import io.reactivex.Single
import org.junit.Test
import org.mockito.BDDMockito.given
import org.mockito.BDDMockito.then
import org.mockito.Mockito.*
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month
import ru.terrakok.gitlabclient.TestData
import ru.terrakok.gitlabclient.TestSchedulers
import ru.terrakok.gitlabclient.di.PrimitiveWrapper
import ru.terrakok.gitlabclient.entity.Author
import ru.terrakok.gitlabclient.entity.OrderBy
import ru.terrakok.gitlabclient.entity.Sort
import ru.terrakok.gitlabclient.entity.app.target.*
import ru.terrakok.gitlabclient.entity.event.Event
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.event.EventTargetType
import ru.terrakok.gitlabclient.model.data.server.GitlabApi
import ru.terrakok.gitlabclient.model.data.server.MarkDownUrlResolver
/**
* @author Vitaliy Belyaev on 21.05.2019.
*/
class EventRepositoryTest {
private val defaultPageSize = 1
private val testPage = 2
private val testEvent = getTestEvent()
private val testProject = TestData.getProject(testEvent.projectId)
private val api = mock(GitlabApi::class.java)
private val markDownUrlResolver = mock(MarkDownUrlResolver::class.java)
private val repository = EventRepository(
api,
TestSchedulers(),
PrimitiveWrapper(defaultPageSize),
markDownUrlResolver)
@Test
fun `get events should filter broken events`() {
// GIVEN
val brokenEvent = testEvent.copy(targetType = EventTargetType.NOTE, note = null)
val testEvents = listOf(testEvent, brokenEvent)
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(testEvents))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
// WHEN
val testObserver = repository.getEvents(page = testPage).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testEvent.projectId)
then(api)
.shouldHaveNoMoreInteractions()
}
@Test
fun `get events should converts dates to string when it provided`() {
// GIVEN
val testBeforeDay = LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0)
val testAfterDay = LocalDateTime.of(2007, Month.DECEMBER, 24, 12, 0)
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testEvent)))
// WHEN
val testObserver = repository
.getEvents(page = testPage, beforeDay = testBeforeDay, afterDay = testAfterDay)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
"2007-12-14",
"2007-12-24",
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
}
@Test
fun `get events should succeed with valid events`() {
// GIVEN
val expectedTargetHeader = getExpectedTargetHeaderForIssue(testEvent)
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testEvent)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
// WHEN
val testObserver = repository.getEvents(page = testPage).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testEvent.projectId)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertResult(listOf(expectedTargetHeader))
}
@Test
fun `get events should return empty list when api returns empty list`() {
// GIVEN
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(emptyList()))
// WHEN
val testObserver = repository.getEvents(page = testPage).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertResult(emptyList())
}
@Test
fun `get events should return error when api returns error`() {
// GIVEN
val error = RuntimeException()
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.error(error))
// WHEN
val testObserver = repository.getEvents(page = testPage).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertNoValues()
.assertError(error)
.assertNotComplete()
}
@Test
fun `get project events should succeed with valid events`() {
// GIVEN
val expectedTargetHeader = getExpectedTargetHeaderForIssue(testEvent)
given(api.getProjectEvents(
anyLong(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testEvent)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
// WHEN
val testObserver = repository
.getProjectEvents(projectId = testProject.id, page = testPage)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProjectEvents(
testProject.id,
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testEvent.projectId)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertResult(listOf(expectedTargetHeader))
}
@Test
fun `get project events should return empty list when api returns empty list`() {
// GIVEN
given(api.getProjectEvents(
anyLong(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(emptyList()))
// WHEN
val testObserver = repository
.getProjectEvents(projectId = testProject.id, page = testPage)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProjectEvents(
testProject.id,
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertResult(emptyList())
}
@Test
fun `get project events should return error when api returns error`() {
// GIVEN
val error = RuntimeException()
given(api.getProjectEvents(
anyLong(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.error(error))
// WHEN
val testObserver = repository
.getProjectEvents(projectId = testProject.id, page = testPage)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProjectEvents(
testProject.id,
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.shouldHaveNoMoreInteractions()
testObserver
.assertNoValues()
.assertError(error)
.assertNotComplete()
}
@Test
fun `get events should succeed with valid diff note event`() {
// GIVEN
val diffNoteEvent = testEvent.copy(targetType = EventTargetType.DIFF_NOTE)
val resolvedBody = "resolved body"
val expectedTargetHeader = getExpectedTargetHeaderForDiffNote(diffNoteEvent, resolvedBody)
given(api.getEvents(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(diffNoteEvent)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
given(markDownUrlResolver.resolve(anyString(), any())).willReturn(resolvedBody)
// WHEN
val testObserver = repository.getEvents(page = testPage).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getEvents(
null,
null,
null,
null,
Sort.DESC,
OrderBy.UPDATED_AT,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testEvent.projectId)
then(api)
.shouldHaveNoMoreInteractions()
then(markDownUrlResolver)
.should(times(1))
.resolve(diffNoteEvent.note!!.body, testProject)
testObserver
.assertResult(listOf(expectedTargetHeader))
}
private fun getTestEvent() = Event(
123L,
EventAction.CREATED,
321L,
4331L,
EventTargetType.ISSUE,
666L,
"title of issue",
LocalDateTime.of(2018, Month.DECEMBER, 13, 12, 0),
Author(1L, "", "", "", "", ""),
"author",
null,
TestData.getNote()
)
private fun getExpectedTargetHeaderForIssue(event: Event): TargetHeader {
return TargetHeader.Public(
event.author,
TargetHeaderIcon.CREATED,
TargetHeaderTitle.Event(
event.author.name,
event.actionName,
"${AppTarget.ISSUE} #${event.targetIid!!}",
testProject.name),
event.targetTitle!!,
event.createdAt,
AppTarget.ISSUE,
event.targetId!!,
TargetInternal(event.projectId, event.targetIid!!),
listOf(TargetBadge.Text(testProject.name, AppTarget.PROJECT, testProject.id),
TargetBadge.Text(event.author.username, AppTarget.USER, event.author.id)),
TargetAction.Undefined
)
}
private fun getExpectedTargetHeaderForDiffNote(event: Event, resolvedBody: String): TargetHeader {
return TargetHeader.Public(
event.author,
TargetHeaderIcon.CREATED,
TargetHeaderTitle.Event(
event.author.name,
event.actionName,
"${AppTarget.ISSUE} #${event.note!!.noteableIid}",
testProject.name),
resolvedBody,
event.createdAt,
AppTarget.ISSUE,
event.note!!.noteableId,
TargetInternal(event.projectId, event.note!!.noteableIid),
listOf(TargetBadge.Text(testProject.name, AppTarget.PROJECT, testProject.id),
TargetBadge.Text(event.author.username, AppTarget.USER, event.author.id)),
TargetAction.Undefined
)
}
}
\ No newline at end of file
package ru.terrakok.gitlabclient.model.repository.issue
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.anyOrNull
import io.reactivex.Single
import org.junit.Test
import org.mockito.BDDMockito.*
import org.mockito.Mockito.mock
import org.mockito.Mockito.times
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month
import ru.terrakok.gitlabclient.TestData
import ru.terrakok.gitlabclient.TestSchedulers
import ru.terrakok.gitlabclient.di.PrimitiveWrapper
import ru.terrakok.gitlabclient.entity.Author
import ru.terrakok.gitlabclient.entity.Note
import ru.terrakok.gitlabclient.entity.Project
import ru.terrakok.gitlabclient.entity.app.target.*
import ru.terrakok.gitlabclient.entity.event.EventAction
import ru.terrakok.gitlabclient.entity.event.EventTargetType
import ru.terrakok.gitlabclient.entity.issue.Issue
import ru.terrakok.gitlabclient.entity.issue.IssueState
import ru.terrakok.gitlabclient.model.data.server.GitlabApi
import ru.terrakok.gitlabclient.model.data.server.MarkDownUrlResolver
/**
* @author Vitaliy Belyaev on 28.05.2019.
*/
class IssueRepositoryTest {
private val defaultPageSize = 1
private val testPage = 2
private val testIssue = getTestIssue()
private val testProject = TestData.getProject(testIssue.projectId)
private val api = mock(GitlabApi::class.java)
private val markDownUrlResolver = mock(MarkDownUrlResolver::class.java)
private val repository = IssueRepository(
api,
TestSchedulers(),
PrimitiveWrapper(defaultPageSize),
markDownUrlResolver)
@Test
fun `get my issues should succeed with valid api response`() {
// GIVEN
val expectedTargetHeader = getExpectedTargetHeader(testIssue, testProject)
given(api.getMyIssues(
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testIssue)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
// WHEN
val testObserver = repository
.getMyIssues(page = testPage, pageSize = defaultPageSize)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getMyIssues(
null,
null,
null,
null,
null,
null,
null,
null,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(listOf(expectedTargetHeader))
}
@Test
fun `get issues should succeed with valid api response`() {
// GIVEN
val expectedTargetHeader = getExpectedTargetHeader(testIssue, testProject)
given(api.getIssues(
anyLong(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testIssue)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
// WHEN
val testObserver = repository
.getIssues(projectId = testIssue.projectId, page = testPage, pageSize = defaultPageSize)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getIssues(
testIssue.projectId,
null,
null,
null,
null,
null,
null,
null,
null,
testPage,
defaultPageSize)
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(listOf(expectedTargetHeader))
}
@Test
fun `get issue should return issue with modified description`() {
// GIVEN
val resolvedBody = "body that differs from issue description"
val expectedIssue = testIssue.copy(description = resolvedBody)
given(api.getIssue(
anyLong(),
anyLong())).willReturn(Single.just(testIssue))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
given(markDownUrlResolver.resolve(anyString(), any())).willReturn(resolvedBody)
// WHEN
val testObserver = repository
.getIssue(testIssue.projectId, testIssue.id)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api)
.should(times(1))
.getIssue(testIssue.projectId, testIssue.id)
then(markDownUrlResolver)
.should(times(1))
.resolve(testIssue.description, testProject)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(expectedIssue)
}
@Test
fun `get issue should return issue without modifications`() {
// GIVEN
val resolvedBody = testIssue.description
given(api.getIssue(
anyLong(),
anyLong())).willReturn(Single.just(testIssue))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
given(markDownUrlResolver.resolve(anyString(), any())).willReturn(resolvedBody)
// WHEN
val testObserver = repository
.getIssue(testIssue.projectId, testIssue.id)
.test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api)
.should(times(1))
.getIssue(testIssue.projectId, testIssue.id)
then(markDownUrlResolver)
.should(times(1))
.resolve(testIssue.description, testProject)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(testIssue)
}
@Test
fun `get issue notes should return notes with modified body`() {
// GIVEN
val testNote = Note(
13L,
"note test body",
Author(1L, "", "", "", "", ""),
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
null,
false,
435L,
EventTargetType.ISSUE,
333L)
val resolvedBody = "body that differs from issue description"
val expected = testNote.copy(body = resolvedBody)
given(api.getIssueNotes(
anyLong(),
anyLong(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testNote)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
given(markDownUrlResolver.resolve(anyString(), any())).willReturn(resolvedBody)
// WHEN
val testObserver = repository.getIssueNotes(
testIssue.projectId,
testIssue.id,
null,
null,
testPage,
defaultPageSize).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api)
.should(times(1))
.getIssueNotes(
testIssue.projectId,
testIssue.id,
null,
null,
testPage,
defaultPageSize)
then(markDownUrlResolver)
.should(times(1))
.resolve(testNote.body, testProject)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(listOf(expected))
}
@Test
fun `get issue notes should return notes without modifications`() {
// GIVEN
val testNote = Note(
13L,
"note test body",
Author(1L, "", "", "", "", ""),
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
null,
false,
435L,
EventTargetType.ISSUE,
333L)
val resolvedBody = testNote.body
given(api.getIssueNotes(
anyLong(),
anyLong(),
anyOrNull(),
anyOrNull(),
anyInt(),
anyInt())).willReturn(Single.just(listOf(testNote)))
given(api.getProject(anyLong(), anyBoolean())).willReturn(Single.just(testProject))
given(markDownUrlResolver.resolve(anyString(), any())).willReturn(resolvedBody)
// WHEN
val testObserver = repository.getIssueNotes(
testIssue.projectId,
testIssue.id,
null,
null,
testPage,
defaultPageSize).test()
testObserver.awaitTerminalEvent()
// THEN
then(api)
.should(times(1))
.getProject(testIssue.projectId, true)
then(api)
.should(times(1))
.getIssueNotes(
testIssue.projectId,
testIssue.id,
null,
null,
testPage,
defaultPageSize)
then(markDownUrlResolver)
.should(times(1))
.resolve(testNote.body, testProject)
then(api).shouldHaveNoMoreInteractions()
testObserver.assertResult(listOf(testNote))
}
@Test
fun `get all issue notes should return notes from all pages`() {
// GIVEN
val testNote = Note(
13L,
"note test body",
Author(1L, "", "", "", "", ""),
LocalDateTime.of(2007, Month.DECEMBER, 14, 11, 0),
null,
false,
435L,
EventTargetType.ISSUE,
333L)
given(api.getIssueNotes(
anyLong(),
anyLong(),
anyOrNull(),
anyOrNull(),