View Videos.kt
internal class Videos(val items: List<Video>) { | |
fun toTalkBuilders(): List<Talk.Builder> { | |
return items.map(Video::toTalkBuilder) | |
} | |
} | |
internal class Video(val id: VideoId, private val snippet: Snippet) { | |
internal fun toTalkBuilder(): Talk.Builder { | |
val videoId = id.videoId | |
return Talk.with { |
View search.json
{ | |
"criteria": { | |
"journeys": [ | |
{ | |
"departureSpacePortId": "http://localhost:1865/spaceports/ddf86b0b-94e3-3566-8486-fd076b9686a6", | |
"departureSchedule": "2020-08-18T10:00", | |
"arrivalSpacePortId": "http://localhost:1865/spaceports/4ed3116c-e359-3245-b8d0-cec742551507" | |
}, | |
{ | |
"departureSpacePortId": "http://localhost:1865/spaceports/4ed3116c-e359-3245-b8d0-cec742551507", |
View Search.kt
@Resource | |
data class Search(private val id: UUID, | |
val criteria: Criteria) : RepresentationModel<Search>() |
View Search.kt
data class Search( | |
val id: UUID = randomUUID(), | |
val criteria: Criteria, | |
val spaceTrains: SpaceTrains, | |
val selection: Selection = Selection()) | |
data class SpaceTrain( | |
val number: String, | |
val bound: Bound, | |
val originId: String, |
View Recommendation.kt
package org.craftsrecords.talkadvisor.infra.resources | |
import org.springframework.hateoas.Identifiable | |
import java.util.* | |
import org.craftsrecords.talkadvisor.recommendation.Recommendation as DomainRecommendation | |
import org.craftsrecords.talkadvisor.recommendation.talk.Talk as DomainTalk | |
class Recommendation(private val id: UUID, val talks: List<Talk>) : Identifiable<UUID> { | |
override fun getId() = id | |
} |
View Preferences.kt
package org.craftsrecords.talkadvisor.infra.resources | |
import org.craftsrecords.talkadvisor.recommendation.preferences.Preferences as DomainPreferences | |
import org.craftsrecords.talkadvisor.recommendation.preferences.Topic as DomainTopic | |
import org.craftsrecords.talkadvisor.recommendation.talk.TalkFormat as DomainTalkFormat | |
data class Preferences(val topics: List<Topic>, val talksFormats: List<String>) { | |
fun toDomainObject(): DomainPreferences { | |
return DomainPreferences(topics.toDomainObjects(), talksFormats.toDomainTalkFormats()) | |
} |
View ProfileController.kt
@RestController | |
@RequestMapping(path = ["/profiles"]) | |
class ProfileController(private val createProfile: CreateProfile) { | |
/** | |
* simulating an authentication context by passing the userId in a header, | |
* no need to set up all the security frameworks for this demo, but never do that in production !!! | |
*/ | |
@PostMapping | |
fun createProfile(@RequestHeader("User-Id") userId: String, @RequestBody preferences: Preferences): ResponseEntity<Profile> { |
View RecommendationStepdefs.kt
package org.craftsrecords.talkadvisor.recommendation.stepdefs | |
import cucumber.api.java.en.Then | |
import cucumber.api.java.en.When | |
import org.craftsrecords.talkadvisor.recommendation.api.RecommendTalks | |
import org.craftsrecords.talkadvisor.recommendation.assertions.that | |
import org.craftsrecords.talkadvisor.recommendation.criteria.GuestCriteria | |
import org.craftsrecords.talkadvisor.recommendation.talk.TalkFormat | |
import java.time.Duration.ofMinutes |
View MockCaveatTest.kt
@Test | |
fun `should retrieve talks`() { | |
val mockedTalk = mock(Talk::class.java) | |
given(mockedTalk.format).willReturn(IGNITE) | |
given(mockedTalk.duration).willReturn(Duration.ofHours(1)) | |
// this resulted Talk Object is invalid, the source of truth is the duration | |
// but here with mockito we overload the format computation logic | |
given(searchTalks.forTopics(anySet())).willReturn(setOf(mockedTalk)) |
View Talk.kt
class Talk private constructor(id: String, | |
title: String, | |
duration: Duration) { | |
val id = notBlank(id, "Cannot create a Talk is a blank id")!! | |
val title = notBlank(title, "Cannot create a Talk is a blank title")!! | |
val duration = notNegative(duration) | |
val format = TalkFormat.ofDuration(duration) | |
} |
NewerOlder