Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
6
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
TalkAdvisor BackEnd
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages & Registries
Packages & Registries
Package Registry
Analytics
Analytics
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
CraftsRecords
TalkAdvisor
TalkAdvisor BackEnd
Commits
b7b75f16
Commit
b7b75f16
authored
Feb 25, 2019
by
Julien Topçu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding controllers
parent
a7cbbf9c
Changes
40
Show whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
474 additions
and
54 deletions
+474
-54
pom.xml
pom.xml
+1
-4
talkadvisor-domain/pom.xml
talkadvisor-domain/pom.xml
+30
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Aggregate.kt
...in/src/main/kotlin/org/craftsrecords/hexarch/Aggregate.kt
+8
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/DomainService.kt
...rc/main/kotlin/org/craftsrecords/hexarch/DomainService.kt
+8
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Repository.kt
...n/src/main/kotlin/org/craftsrecords/hexarch/Repository.kt
+8
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Stub.kt
...-domain/src/main/kotlin/org/craftsrecords/hexarch/Stub.kt
+8
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/Recommendation.kt
...raftsrecords/talkadvisor/recommendation/Recommendation.kt
+2
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/TalksAdvisor.kt
.../craftsrecords/talkadvisor/recommendation/TalksAdvisor.kt
+5
-3
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/Profile.kt
...aftsrecords/talkadvisor/recommendation/profile/Profile.kt
+0
-2
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileAlreadyExistsException.kt
...r/recommendation/profile/ProfileAlreadyExistsException.kt
+3
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileCreator.kt
...ords/talkadvisor/recommendation/profile/ProfileCreator.kt
+5
-3
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileNotFoundException.kt
...dvisor/recommendation/profile/ProfileNotFoundException.kt
+3
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/Profiles.kt
.../craftsrecords/talkadvisor/recommendation/spi/Profiles.kt
+4
-2
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/Recommendations.kt
...records/talkadvisor/recommendation/spi/Recommendations.kt
+3
-1
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/HardCodedTalksSearcher.kt
...dvisor/recommendation/spi/stubs/HardCodedTalksSearcher.kt
+2
-0
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/InMemoryProfiles.kt
.../talkadvisor/recommendation/spi/stubs/InMemoryProfiles.kt
+6
-4
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/InMemoryRecommendations.kt
...visor/recommendation/spi/stubs/InMemoryRecommendations.kt
+4
-1
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/RandomExtension.kt
...t/kotlin/org/craftsrecords/talkadvisor/RandomExtension.kt
+6
-0
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationFunctionalTests.kt
...lkadvisor/recommendation/RecommendationFunctionalTests.kt
+3
-3
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationTest.kt
...srecords/talkadvisor/recommendation/RecommendationTest.kt
+1
-1
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/ProfileAssert.kt
...ds/talkadvisor/recommendation/assertions/ProfileAssert.kt
+0
-2
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/RecommendationAssert.kt
...advisor/recommendation/assertions/RecommendationAssert.kt
+0
-7
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/TalkAsserts.kt
...ords/talkadvisor/recommendation/assertions/TalkAsserts.kt
+0
-11
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/criteria/CriteriaFactory.kt
...ds/talkadvisor/recommendation/criteria/CriteriaFactory.kt
+3
-3
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileFactory.kt
...ords/talkadvisor/recommendation/profile/ProfileFactory.kt
+7
-0
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileFunctionalTests.kt
...kadvisor/recommendation/profile/ProfileFunctionalTests.kt
+13
-0
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileTest.kt
...records/talkadvisor/recommendation/profile/ProfileTest.kt
+1
-0
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/stepdefs/ProfileStepdefs.kt
...ds/talkadvisor/recommendation/stepdefs/ProfileStepdefs.kt
+28
-4
talkadvisor-domain/src/test/resources/features/profiles.feature
...visor-domain/src/test/resources/features/profiles.feature
+6
-0
talkadvisor-infra/pom.xml
talkadvisor-infra/pom.xml
+94
-0
talkadvisor-infra/src/main/kotlin/org/craftsrecords/talkadvisor/TalkAdvisorApplication.kt
...n/org/craftsrecords/talkadvisor/TalkAdvisorApplication.kt
+1
-1
talkadvisor-infra/src/main/kotlin/org/craftsrecords/talkadvisor/configurations/DomainConfiguration.kt
...records/talkadvisor/configurations/DomainConfiguration.kt
+15
-0
talkadvisor-infra/src/main/kotlin/org/craftsrecords/talkadvisor/controller/ProfileController.kt
...craftsrecords/talkadvisor/controller/ProfileController.kt
+35
-0
talkadvisor-infra/src/main/kotlin/org/craftsrecords/talkadvisor/resources/Preferences.kt
...in/org/craftsrecords/talkadvisor/resources/Preferences.kt
+13
-0
talkadvisor-infra/src/main/kotlin/org/craftsrecords/talkadvisor/resources/Profile.kt
...kotlin/org/craftsrecords/talkadvisor/resources/Profile.kt
+12
-0
talkadvisor-infra/src/test/kotlin/org/craftsrecords/talkadvisor/TalkAdvisorApplicationTests.kt
.../craftsrecords/talkadvisor/TalkAdvisorApplicationTests.kt
+1
-2
talkadvisor-infra/src/test/kotlin/org/craftsrecords/talkadvisor/controller/ProfileControllerIT.kt
...aftsrecords/talkadvisor/controller/ProfileControllerIT.kt
+69
-0
talkadvisor-infra/src/test/kotlin/org/craftsrecords/talkadvisor/resources/PreferencesTest.kt
...rg/craftsrecords/talkadvisor/resources/PreferencesTest.kt
+33
-0
talkadvisor-infra/src/test/kotlin/org/craftsrecords/talkadvisor/resources/ProfileTest.kt
...in/org/craftsrecords/talkadvisor/resources/ProfileTest.kt
+19
-0
talkadvisor-infra/src/test/resources/payloads/create-profile-request.json
...a/src/test/resources/payloads/create-profile-request.json
+14
-0
No files found.
pom.xml
View file @
b7b75f16
...
...
@@ -40,7 +40,7 @@
<plugins>
<plugin>
<artifactId>
maven-enforcer-plugin
</artifactId>
<version>
3.0.0-M
2
</version>
<version>
3.0.0-M
1
</version>
<executions>
<execution>
<id>
dependencies-sanitization
</id>
...
...
@@ -93,9 +93,6 @@
<args>
<arg>
-Xjsr305=strict
</arg>
</args>
<compilerPlugins>
<plugin>
spring
</plugin>
</compilerPlugins>
<jvmTarget>
1.8
</jvmTarget>
<javaParameters>
true
</javaParameters>
</configuration>
...
...
talkadvisor-domain/pom.xml
View file @
b7b75f16
...
...
@@ -39,6 +39,36 @@
</execution>
</executions>
</plugin>
<plugin>
<artifactId>
kotlin-maven-plugin
</artifactId>
<groupId>
org.jetbrains.kotlin
</groupId>
<configuration>
<compilerPlugins>
<plugin>
all-open
</plugin>
</compilerPlugins>
<pluginOptions>
<option>
all-open:annotation=org.craftsrecords.hexarch.DomainService
</option>
<option>
all-open:annotation=org.craftsrecords.hexarch.Stub
</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>
org.jetbrains.kotlin
</groupId>
<artifactId>
kotlin-maven-allopen
</artifactId>
<version>
${kotlin.version}
</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<artifactId>
maven-jar-plugin
</artifactId>
<executions>
<execution>
<goals>
<goal>
test-jar
</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
...
...
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Aggregate.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.hexarch
import
java.lang.annotation.Inherited
@Retention
(
AnnotationRetention
.
SOURCE
)
@Target
(
AnnotationTarget
.
CLASS
)
@Inherited
annotation
class
Aggregate
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/DomainService.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.hexarch
import
java.lang.annotation.Inherited
@Retention
(
AnnotationRetention
.
RUNTIME
)
@Target
(
AnnotationTarget
.
CLASS
)
@Inherited
annotation
class
DomainService
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Repository.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.hexarch
import
java.lang.annotation.Inherited
@Retention
(
AnnotationRetention
.
SOURCE
)
@Target
(
AnnotationTarget
.
CLASS
)
@Inherited
annotation
class
Repository
talkadvisor-domain/src/main/kotlin/org/craftsrecords/hexarch/Stub.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.hexarch
import
java.lang.annotation.Inherited
@Retention
(
AnnotationRetention
.
RUNTIME
)
@Target
(
AnnotationTarget
.
CLASS
)
@Inherited
annotation
class
Stub
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/Recommendation.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation
import
org.craftsrecords.hexarch.Aggregate
import
org.craftsrecords.talkadvisor.recommendation.criteria.Criteria
import
org.craftsrecords.talkadvisor.recommendation.talk.Talk
import
java.util.*
@Aggregate
class
Recommendation
(
val
id
:
UUID
=
UUID
.
randomUUID
(),
talks
:
Set
<
Talk
>,
val
criteria
:
Criteria
)
{
val
talks
=
talks
.
toSet
()
...
...
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/TalksAdvisor.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation
import
org.craftsrecords.hexarch.DomainService
import
org.craftsrecords.talkadvisor.recommendation.api.RecommendTalks
import
org.craftsrecords.talkadvisor.recommendation.criteria.Criteria
import
org.craftsrecords.talkadvisor.recommendation.criteria.GuestCriteria
import
org.craftsrecords.talkadvisor.recommendation.profile.ProfileNotFoundException
import
org.craftsrecords.talkadvisor.recommendation.spi.Profiles
import
org.craftsrecords.talkadvisor.recommendation.spi.Recommendations
import
org.craftsrecords.talkadvisor.recommendation.spi.SearchTalks
import
org.craftsrecords.talkadvisor.recommendation.talk.Talk
@DomainService
class
TalksAdvisor
(
private
val
searchTalks
:
SearchTalks
,
private
val
recommendations
:
Recommendations
,
private
val
profiles
:
Profiles
)
:
RecommendTalks
{
override
fun
to
(
userId
:
String
):
Recommendation
{
val
profile
=
profiles
.
fetch
(
userId
)
val
profile
=
profiles
.
fetch
(
userId
)
?:
throw
ProfileNotFoundException
(
userId
)
return
recommendTalksSatisfying
(
profile
.
preferences
)
}
...
...
@@ -24,8 +27,7 @@ class TalksAdvisor(private val searchTalks: SearchTalks,
private
fun
recommendTalksSatisfying
(
criteria
:
Criteria
):
Recommendation
{
val
talks
=
retrieveTalksSatisfying
(
criteria
)
val
recommendation
=
Recommendation
(
criteria
=
criteria
,
talks
=
talks
)
recommendations
.
save
(
recommendation
)
return
recommendation
return
recommendations
.
save
(
recommendation
)
}
private
fun
retrieveTalksSatisfying
(
criteria
:
Criteria
):
Set
<
Talk
>
{
...
...
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/Profile.kt
View file @
b7b75f16
...
...
@@ -21,6 +21,4 @@ class Profile(id: String, val preferences: Preferences) {
override
fun
hashCode
():
Int
{
return
id
.
hashCode
()
}
}
\ No newline at end of file
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileAlreadyExistsException.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.profile
class
ProfileAlreadyExistsException
(
userId
:
String
)
:
RuntimeException
(
"A profile already exists for the user $userId"
)
\ No newline at end of file
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileCreator.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.profile
import
org.craftsrecords.hexarch.DomainService
import
org.craftsrecords.talkadvisor.recommendation.api.CreateProfile
import
org.craftsrecords.talkadvisor.recommendation.preferences.Preferences
import
org.craftsrecords.talkadvisor.recommendation.spi.Profiles
class
ProfileCreator
(
val
profiles
:
Profiles
)
:
CreateProfile
{
@DomainService
class
ProfileCreator
(
private
val
profiles
:
Profiles
)
:
CreateProfile
{
override
fun
forUserWithPreferences
(
userId
:
String
,
preferences
:
Preferences
):
Profile
{
val
profile
=
Profile
(
userId
,
preferences
)
profiles
.
save
(
profile
)
return
profile
profiles
.
fetch
(
userId
)
?.
let
{
throw
ProfileAlreadyExistsException
(
userId
)
}
return
profile
s
.
save
(
profile
)
}
}
\ No newline at end of file
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/
NoProfile
FoundException.kt
→
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/
ProfileNot
FoundException.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.profile
class
NoProfileFoundException
(
val
userId
:
String
)
:
RuntimeException
(
"No profile found to the user $userId"
)
\ No newline at end of file
class
ProfileNotFoundException
(
val
userId
:
String
)
:
RuntimeException
(
"No profile found for the user $userId"
)
\ No newline at end of file
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/Profiles.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.spi
import
org.craftsrecords.hexarch.Repository
import
org.craftsrecords.talkadvisor.recommendation.profile.Profile
@Repository
interface
Profiles
{
fun
save
(
profile
:
Profile
)
fun
save
(
profile
:
Profile
)
:
Profile
fun
fetch
(
userId
:
String
):
Profile
fun
fetch
(
userId
:
String
):
Profile
?
}
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/Recommendations.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.spi
import
org.craftsrecords.hexarch.Repository
import
org.craftsrecords.talkadvisor.recommendation.Recommendation
@Repository
interface
Recommendations
{
fun
save
(
recommendation
:
Recommendation
)
fun
save
(
recommendation
:
Recommendation
)
:
Recommendation
}
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/HardCodedTalksSearcher.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.spi.stubs
import
org.craftsrecords.hexarch.Stub
import
org.craftsrecords.talkadvisor.recommendation.preferences.Topic
import
org.craftsrecords.talkadvisor.recommendation.spi.SearchTalks
import
org.craftsrecords.talkadvisor.recommendation.talk.Talk
import
java.time.Duration
import
kotlin.random.Random
@Stub
class
HardCodedTalksSearcher
:
SearchTalks
{
override
fun
forTopics
(
topics
:
Set
<
Topic
>):
Set
<
Talk
>
{
return
createTalks
(
topics
)
...
...
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/InMemoryProfiles.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.spi.stubs
import
org.craftsrecords.
talkadvisor.recommendation.profile.NoProfileFoundException
import
org.craftsrecords.
hexarch.Stub
import
org.craftsrecords.talkadvisor.recommendation.profile.Profile
import
org.craftsrecords.talkadvisor.recommendation.spi.Profiles
@Stub
class
InMemoryProfiles
(
private
val
profiles
:
MutableMap
<
String
,
Profile
>
=
HashMap
())
:
Profiles
{
override
fun
fetch
(
userId
:
String
):
Profile
{
return
profiles
[
userId
]
?:
throw
NoProfileFoundException
(
userId
)
override
fun
fetch
(
userId
:
String
):
Profile
?
{
return
profiles
[
userId
]
}
override
fun
save
(
profile
:
Profile
)
{
override
fun
save
(
profile
:
Profile
)
:
Profile
{
profiles
[
profile
.
id
]
=
profile
return
profile
}
}
\ No newline at end of file
talkadvisor-domain/src/main/kotlin/org/craftsrecords/talkadvisor/recommendation/spi/stubs/InMemoryRecommendations.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.spi.stubs
import
org.craftsrecords.hexarch.Stub
import
org.craftsrecords.talkadvisor.recommendation.Recommendation
import
org.craftsrecords.talkadvisor.recommendation.spi.Recommendations
import
java.util.*
@Stub
class
InMemoryRecommendations
(
private
val
recommendations
:
MutableMap
<
UUID
,
Recommendation
>
=
HashMap
())
:
Recommendations
{
override
fun
save
(
recommendation
:
Recommendation
)
{
override
fun
save
(
recommendation
:
Recommendation
)
:
Recommendation
{
recommendations
[
recommendation
.
id
]
=
recommendation
return
recommendation
}
}
\ No newline at end of file
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/RandomExtension.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.talkadvisor
import
java.nio.charset.Charset
import
kotlin.random.Random
fun
Random
.
nextString
()
=
String
(
Random
.
nextBytes
(
4
),
Charset
.
defaultCharset
())
\ No newline at end of file
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/
RunCucumberTest
.kt
→
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/
recommendation/RecommendationFunctionalTests
.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor
package
org.craftsrecords.talkadvisor
.recommendation
import
cucumber.api.CucumberOptions
import
cucumber.api.junit.Cucumber
import
org.junit.runner.RunWith
@RunWith
(
Cucumber
::
class
)
@CucumberOptions
(
strict
=
true
,
plugin
=
[
"pretty"
,
"html:target/cucumber"
],
features
=
[
"classpath:features/"
])
class
RunCucumberTest
\ No newline at end of file
@CucumberOptions
(
strict
=
true
,
plugin
=
[
"pretty"
,
"html:target/cucumber"
],
features
=
[
"classpath:features/recommendations.feature"
])
class
RecommendationFunctionalTests
\ No newline at end of file
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/RecommendationTest.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation
import
org.assertj.core.api.Assertions.assertThat
import
org.craftsrecords.talkadvisor.recommendation.
profile
.createCriteria
import
org.craftsrecords.talkadvisor.recommendation.
criteria
.createCriteria
import
org.craftsrecords.talkadvisor.recommendation.talk.createTalk
import
org.craftsrecords.talkadvisor.recommendation.talk.createTalks
import
org.junit.jupiter.api.Test
...
...
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/ProfileAssert.kt
View file @
b7b75f16
...
...
@@ -8,12 +8,10 @@ class ProfileAssert(actual: Profile) : AbstractAssert<ProfileAssert, Profile>(
actual
,
ProfileAssert
::
class
.
java
)
{
@JvmName
(
"correspondsToUser"
)
infix
fun
`corresponds
to
user`
(
userId
:
String
)
{
matches
({
actual
.
id
==
userId
},
"profile id corresponds to userId"
)
}
@JvmName
(
"hasPreferences"
)
infix
fun
`has
preferences`
(
preferences
:
Preferences
)
{
matches
({
actual
.
preferences
==
preferences
},
"matching expected preferences"
)
}
...
...
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/RecommendationAssert.kt
View file @
b7b75f16
...
...
@@ -12,12 +12,10 @@ class RecommendationAssert(actual: Recommendation) : AbstractAssert<Recommendati
RecommendationAssert
::
class
.
java
)
{
@JvmName
(
"hasTalks"
)
fun
hasTalks
()
{
matches
({
it
.
talks
.
isNotEmpty
()
},
"has talks"
)
}
@JvmName
(
"hasTalksRelatedTo"
)
infix
fun
`has
talks
related
to`
(
topicName
:
String
)
{
matches
({
it
.
criteria
.
topics
.
any
{
topic
->
topic
.
name
==
topicName
}
...
...
@@ -26,7 +24,6 @@ class RecommendationAssert(actual: Recommendation) : AbstractAssert<Recommendati
actual
.
talks
.
those
`are
related
to
topic`
topicName
}
@JvmName
(
"hasTalksRelatedTo"
)
infix
fun
`has
talks
related
to`
(
topics
:
Set
<
Topic
>)
{
matches
({
it
.
criteria
.
topics
.
all
{
topic
->
topics
.
contains
(
topic
)
}
...
...
@@ -35,7 +32,6 @@ class RecommendationAssert(actual: Recommendation) : AbstractAssert<Recommendati
actual
.
talks
.
those
`are
related
to
topics`
topics
}
@JvmName
(
"hasOnlyTalksInTheFormat"
)
infix
fun
`has
only
talks
in
the
format`
(
talkFormat
:
TalkFormat
)
{
matches
({
it
.
criteria
.
talksFormats
.
all
{
format
->
format
==
talkFormat
}
...
...
@@ -44,12 +40,10 @@ class RecommendationAssert(actual: Recommendation) : AbstractAssert<Recommendati
actual
.
talks
.
those
`are
in
the
format`
talkFormat
}
@JvmName
(
"hasOnlyTalksHavingTheirDurationIn"
)
infix
fun
`has
only
talks
having
their
duration
in
`
(
range
:
ClosedRange
<
Duration
>)
{
actual
.
talks
.
those
`have
their
duration
in
`
range
}
@JvmName
(
"hasOnlyTalksInTheFormats"
)
infix
fun
`has
only
talks
in
the
formats`
(
talksFormats
:
Set
<
TalkFormat
>)
{
matches
({
it
.
criteria
.
talksFormats
.
all
{
talkFormat
->
talksFormats
.
contains
(
talkFormat
)
}
...
...
@@ -57,7 +51,6 @@ class RecommendationAssert(actual: Recommendation) : AbstractAssert<Recommendati
actual
.
talks
.
those
`have
their
format
in
`
talksFormats
}
@JvmName
(
"correspondsToTheCriteria"
)
infix
fun
`corresponds
to
the
criteria`
(
criteria
:
Criteria
)
{
matches
({
it
.
criteria
==
criteria
},
"corresponds to the given criteria"
)
}
...
...
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/assertions/TalkAsserts.kt
View file @
b7b75f16
...
...
@@ -16,32 +16,26 @@ class TalksAssert(actual: Iterable<Talk>) : AbstractIterableAssert<TalksAssert,
return
TalkAssert
(
talk
).
`as`
(
description
)
}
@JvmName
(
"areRelatedToTopic"
)
infix
fun
`are
related
to
topic`
(
topicName
:
String
)
{
allSatisfy
{
TalkAssert
(
it
)
`is
related
to
topic`
topicName
}
}
@JvmName
(
"areRelatedToTopic"
)
infix
fun
`are
related
to
topics`
(
topics
:
Set
<
Topic
>)
{
allSatisfy
{
TalkAssert
(
it
)
`is
related
to
a
topic
in
`
topics
}
}
@JvmName
(
"areInTheFormat"
)
infix
fun
`are
in
the
format`
(
talkFormat
:
TalkFormat
)
{
allSatisfy
{
TalkAssert
(
it
)
`is
in
the
format`
talkFormat
}
}
@JvmName
(
"haveTheirFormatIn"
)
infix
fun
`have
their
format
in
`
(
talksFormats
:
Set
<
TalkFormat
>)
{
allSatisfy
{
TalkAssert
(
it
)
`has
its
format
in
`
talksFormats
}
}
@JvmName
(
"haveTheirDurationIn"
)
infix
fun
`have
their
duration
in
`
(
range
:
ClosedRange
<
Duration
>)
{
allSatisfy
{
TalkAssert
(
it
)
`has
its
duration
in
`
range
...
...
@@ -54,28 +48,23 @@ class TalkAssert(actual: Talk) : AbstractAssert<TalkAssert, Talk>(
TalkAssert
::
class
.
java
)
{
@JvmName
(
"isRelatedToTopic"
)
infix
fun
`is
related
to
topic`
(
topicName
:
String
)
{
matches
({
it
.
title
.
contains
(
topicName
)
},
"is related to topic $topicName"
)
}
@JvmName
(
"isInTheFormat"
)
infix
fun
`is
in
the
format`
(
talkFormat
:
TalkFormat
)
{
matches
({
it
.
format
==
talkFormat
},
"correspond explicitly to the format $talkFormat"
)
}
@JvmName
(
"hasItsFormatIn"
)
infix
fun
`has
its
format
in
`
(
talksFormats
:
Set
<
TalkFormat
>)
{
matches
({
talksFormats
.
any
{
it
==
actual
.
format
}
},
"has its format in the expected ones"
)
}
@JvmName
(
"hasItsDurationIn"
)
infix
fun
`has
its
duration
in
`
(
range
:
ClosedRange
<
Duration
>)
{
matches
({
it
.
duration
.
coerceIn
(
range
)
==
it
.
duration
},
"duration is in the expected range"
)
}
@JvmName
(
"isRelatedToATopicIn"
)
infix
fun
`is
related
to
a
topic
in
`
(
topics
:
Set
<
Topic
>)
{
matches
({
topics
.
any
{
actual
.
title
.
contains
(
it
.
name
)
}
},
"is related to a topic in"
)
}
...
...
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/
profile
/CriteriaFactory.kt
→
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/
criteria
/CriteriaFactory.kt
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.
profile
package
org.craftsrecords.talkadvisor.recommendation.
criteria
import
org.craftsrecords.talkadvisor.
recommendation.criteria.Criteria
import
org.craftsrecords.talkadvisor.
nextString
import
org.craftsrecords.talkadvisor.recommendation.preferences.Preferences
import
org.craftsrecords.talkadvisor.recommendation.preferences.Topic
import
org.craftsrecords.talkadvisor.recommendation.talk.TalkFormat
...
...
@@ -8,7 +8,7 @@ import kotlin.random.Random
fun
createPreferences
()
=
Preferences
(
setOf
(
Topic
(
Random
.
next
Int
().
toString
()),
Topic
(
Random
.
nextInt
().
to
String
())),
setOf
(
Topic
(
Random
.
next
String
()),
Topic
(
Random
.
next
String
())),
setOf
(
TalkFormat
.
CONFERENCE
,
TalkFormat
.
QUICKIE
))
fun
createCriteria
():
Criteria
=
createPreferences
()
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileFactory.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.profile
import
org.craftsrecords.talkadvisor.nextString
import
org.craftsrecords.talkadvisor.recommendation.criteria.createPreferences
import
kotlin.random.Random
fun
createProfile
()
=
Profile
(
Random
.
nextString
(),
createPreferences
())
\ No newline at end of file
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileFunctionalTests.kt
0 → 100644
View file @
b7b75f16
package
org.craftsrecords.talkadvisor.recommendation.profile
import
cucumber.api.CucumberOptions
import
cucumber.api.junit.Cucumber
import
org.junit.runner.RunWith
@RunWith
(
Cucumber
::
class
)
@CucumberOptions
(
strict
=
true
,
plugin
=
[
"pretty"
,
"html:target/cucumber"
],
features
=
[
"classpath:features/profiles.feature"
],
glue
=
[
"classpath:org.craftsrecords.talkadvisor.recommendation.stepdefs"
])
class
ProfileFunctionalTests
\ No newline at end of file
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/profile/ProfileTest.kt
View file @
b7b75f16
...
...
@@ -2,6 +2,7 @@ package org.craftsrecords.talkadvisor.recommendation.profile
import
org.assertj.core.api.Assertions.assertThat
import
org.assertj.core.api.Assertions.assertThatThrownBy
import
org.craftsrecords.talkadvisor.recommendation.criteria.createPreferences
import
org.junit.jupiter.api.Test
internal
class
ProfileTest
{
...
...
talkadvisor-domain/src/test/kotlin/org/craftsrecords/talkadvisor/recommendation/stepdefs/ProfileStepdefs.kt
View file @
b7b75f16
...
...
@@ -6,10 +6,11 @@ import cucumber.api.java.en.When
import
org.assertj.core.api.Assertions.assertThat
import
org.craftsrecords.talkadvisor.recommendation.api.CreateProfile
import
org.craftsrecords.talkadvisor.recommendation.assertions.that
import
org.craftsrecords.talkadvisor.recommendation.criteria.createPreferences
import
org.craftsrecords.talkadvisor.recommendation.preferences.Preferences
import
org.craftsrecords.talkadvisor.recommendation.profile.NoProfileFoundException
import
org.craftsrecords.talkadvisor.recommendation.profile.Profile
import
org.craftsrecords.talkadvisor.recommendation.profile.createPreferences
import
org.craftsrecords.talkadvisor.recommendation.profile.ProfileAlreadyExistsException
import
org.craftsrecords.talkadvisor.recommendation.profile.ProfileNotFoundException
import
org.craftsrecords.talkadvisor.recommendation.spi.Profiles
class
ProfileStepdefs
(
private
val
testContext
:
TestContext
,
...
...
@@ -26,6 +27,12 @@ class ProfileStepdefs(private val testContext: TestContext,
testContext
.
userId
=
"noProfileUser"
}
@Given
(
"^he already has a profile$"
)
fun
`he
already
has
a
profile`
()
{
val
profile
=
Profile
(
testContext
.
userId
,
createPreferences
())
profiles
.
save
(
profile
)
}
@Given
(
"^he has stored his preferences in his profile$"
)
fun
`he
has
stored
his
preferences
in
his
profile`
()
{
val
profile
=
createProfile
(
testContext
.
userId
)
...
...
@@ -44,6 +51,15 @@ class ProfileStepdefs(private val testContext: TestContext,
testContext
.
createdProfile
=
profile
}
@When
(
"^he tries to create again his profile$"
)
fun
`he
tries
to
create
again
his
profile`
()
{
try
{
createProfile
.
forUserWithPreferences
(
testContext
.
userId
,
createPreferences
())
}
catch
(
e
:
Exception
)
{
testContext
.
error
=
e
}
}
@Then
(
"^his preferences are stored within$"
)
fun
`his
preferences
are
stored
within`
()
{
val
profile
=
testContext
.
createdProfile
...
...
@@ -58,8 +74,16 @@ class ProfileStepdefs(private val testContext: TestContext,
fun
`he
is
notified
that
his
profile
cannot
be
found`
()
{
assertThat
(
testContext
.
error
)
.
isNotNull
()
.
isInstanceOf
(
NoProfileFoundException
::
class
.
java
)
.
hasMessage
(
String
.
format
(
"No profile found to the user %s"
,
testContext
.
userId
))
.
isInstanceOf
(
ProfileNotFoundException
::
class
.
java
)
.
hasMessage
(
String
.
format
(
"No profile found for the user %s"
,
testContext
.
userId
))
}
@Then
(
"^he is notified that his profile already exists$"
)
fun
`he
is
notified
that
his
profile
already
exists`
()
{
assertThat
(
testContext
.
error
)
.
isNotNull
()
.
isInstanceOf
(
ProfileAlreadyExistsException
::
class
.
java
)
.
hasMessage
(
String
.
format
(
"A profile already exists for the user %s"
,
testContext
.
userId
))
}
private
fun
createProfile
(
userId
:
String
):
Profile
{
...
...
talkadvisor-domain/src/test/resources/features/profile
-creation
.feature
→
talkadvisor-domain/src/test/resources/features/profile
s
.feature
View file @
b7b75f16
...
...
@@ -11,3 +11,9 @@ Feature: As a frequent user,
|
QUICKIE
|
CONFERENCE
|
When
he creates his profile
Then
his preferences are stored within
Scenario
:
A
user is trying to create a profile which already exists
Given
a user
And
he already has a profile
When
he tries to create again his profile
Then
he is notified that his profile already exists
talkadvisor-infra/pom.xml
View file @
b7b75f16
...
...
@@ -11,26 +11,120 @@
<artifactId>
talkadvisor-infra
</artifactId>
<properties>