From 8d6c727c091971f06a5c1151f12986902eb0aee3 Mon Sep 17 00:00:00 2001 From: germano Date: Fri, 10 May 2019 23:35:24 -0300 Subject: [PATCH 01/31] initial commit --- .gitmodules | 6 ++ build.gradle | 55 +++++++++++++++++++ settings.gradle | 11 +--- .../java/hive/player/PlayerApplication.java | 18 ++++++ 4 files changed, 81 insertions(+), 9 deletions(-) create mode 100644 .gitmodules create mode 100644 build.gradle create mode 100644 src/main/java/hive/player/PlayerApplication.java diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..96c80b9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "pandora"] + path = pandora + url = https://github.com/hex-g/pandora.git +[submodule "ishigami"] + path = ishigami + url = https://github.com/hex-g/ishigami.git diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..b7c08ff --- /dev/null +++ b/build.gradle @@ -0,0 +1,55 @@ +buildscript { + ext { + springBootVersion = '2.1.3.RELEASE' + springCloudVersion = 'Greenwich.SR1' + } + repositories { + mavenCentral() + maven { url 'https://repo.spring.io/milestone' } + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" as Object + classpath "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" as Object + } +} + +plugins { + id "io.spring.dependency-management" version "1.0.5.RELEASE" + id 'java' + id 'org.springframework.boot' version '2.1.3.RELEASE' +} + +apply plugin: 'io.spring.dependency-management' + +group = 'hive' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '11' + +repositories { + mavenCentral() + maven { url 'https://repo.spring.io/milestone' } +} + +dependencies { + implementation project(':pandora') + implementation project(':ishigami') + + implementation 'javax.xml.bind:jaxb-api:2.3.1' + implementation 'javax.activation:activation:1.1.1' + implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.2' + + implementation 'io.jsonwebtoken:jjwt:0.9.1' + implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul' + testImplementation 'org.springframework.boot:spring-boot-starter-test' +} + +dependencyManagement { + imports { + mavenBom "org.springframework.boot:spring-boot-dependencies:${springBootVersion}" + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} diff --git a/settings.gradle b/settings.gradle index 1b12350..7683048 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,3 @@ -/* - * This file was generated by the Gradle 'init' task. - * - * The settings file is used to specify which projects to include in your build. - * - * Detailed information about configuring a multi-project build in Gradle can be found - * in the user manual at https://docs.gradle.org/5.2.1/userguide/multi_project_builds.html - */ - rootProject.name = 'player' +include 'pandora' +include 'ishigami' diff --git a/src/main/java/hive/player/PlayerApplication.java b/src/main/java/hive/player/PlayerApplication.java new file mode 100644 index 0000000..14969d6 --- /dev/null +++ b/src/main/java/hive/player/PlayerApplication.java @@ -0,0 +1,18 @@ +package hive.player; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; +import org.springframework.cloud.netflix.zuul.EnableZuulProxy; +import org.springframework.context.annotation.PropertySource; + +@SpringBootApplication +@EnableZuulProxy +@EnableEurekaClient +@EntityScan(basePackages = {"hive.ishigami.entity"}) +@PropertySource("classpath:ishigami.properties") +public class PlayerApplication { + public static void main(String[] args) { + SpringApplication.run(PlayerApplication.class, args); + } +} From c96acef5bb1f4e9b55656cbf90441186f747a7c2 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 12 May 2019 00:43:06 -0300 Subject: [PATCH 02/31] initial commit --- .gitmodules | 3 - build.gradle | 10 ++- .../java/hive/player/PlayerApplication.java | 4 - .../player/controller/PlayerController.java | 85 +++++++++++++++++++ src/main/java/hive/player/entity/Player.java | 76 +++++++++++++++++ .../hive/player/entity/PlayerOptions.java | 30 +++++++ .../java/hive/player/entity/PlayerSocial.java | 17 ++++ .../player/repository/PlayerRepository.java | 12 +++ src/main/resources/application.properties | 16 ++++ 9 files changed, 242 insertions(+), 11 deletions(-) create mode 100644 src/main/java/hive/player/controller/PlayerController.java create mode 100644 src/main/java/hive/player/entity/Player.java create mode 100644 src/main/java/hive/player/entity/PlayerOptions.java create mode 100644 src/main/java/hive/player/entity/PlayerSocial.java create mode 100644 src/main/java/hive/player/repository/PlayerRepository.java create mode 100644 src/main/resources/application.properties diff --git a/.gitmodules b/.gitmodules index 96c80b9..631767f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "pandora"] path = pandora url = https://github.com/hex-g/pandora.git -[submodule "ishigami"] - path = ishigami - url = https://github.com/hex-g/ishigami.git diff --git a/build.gradle b/build.gradle index b7c08ff..0fcfa64 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ plugins { id 'org.springframework.boot' version '2.1.3.RELEASE' } +apply plugin: 'groovy' apply plugin: 'io.spring.dependency-management' group = 'hive' @@ -32,19 +33,20 @@ repositories { dependencies { implementation project(':pandora') - implementation project(':ishigami') implementation 'javax.xml.bind:jaxb-api:2.3.1' implementation 'javax.activation:activation:1.1.1' implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.2' - implementation 'io.jsonwebtoken:jjwt:0.9.1' implementation 'org.springframework.boot:spring-boot-starter-web' - implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'com.h2database:h2' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' - implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testCompile( + 'org.hamcrest:hamcrest-core:1.3',//if not using delete this + 'org.spockframework:spock-core:1.3-groovy-2.5' + ) } dependencyManagement { diff --git a/src/main/java/hive/player/PlayerApplication.java b/src/main/java/hive/player/PlayerApplication.java index 14969d6..f34049a 100644 --- a/src/main/java/hive/player/PlayerApplication.java +++ b/src/main/java/hive/player/PlayerApplication.java @@ -3,14 +3,10 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; -import org.springframework.cloud.netflix.zuul.EnableZuulProxy; import org.springframework.context.annotation.PropertySource; @SpringBootApplication -@EnableZuulProxy @EnableEurekaClient -@EntityScan(basePackages = {"hive.ishigami.entity"}) -@PropertySource("classpath:ishigami.properties") public class PlayerApplication { public static void main(String[] args) { SpringApplication.run(PlayerApplication.class, args); diff --git a/src/main/java/hive/player/controller/PlayerController.java b/src/main/java/hive/player/controller/PlayerController.java new file mode 100644 index 0000000..9906c1c --- /dev/null +++ b/src/main/java/hive/player/controller/PlayerController.java @@ -0,0 +1,85 @@ +package hive.player.controller; + +import static hive.pandora.constant.HiveInternalHeaders.*; + +import com.netflix.client.http.HttpResponse; +import hive.player.entity.Player; +import hive.player.entity.PlayerOptions; +import hive.player.entity.PlayerSocial; +import hive.player.repository.PlayerRepository; +import org.apache.coyote.Response; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Optional; + +@RestController +@RequestMapping("/") +public class PlayerController { + + @Autowired PlayerRepository playerRepository; + public void createUser(){ + var social=new PlayerSocial("git","linkedin","@twitter"); + var options = new PlayerOptions( + "ouro", + "titan do café", + "on", + "on", + "on", + "on"); + var player=new Player( + 1, + "alias", + "email", + "11985054202", + "String grande", + "21/04/1998", + "46358570855", + options, + social); + playerRepository.save(player); + player=new Player( + 2, + "germano", + "email", + "11985055502", + "String grande Lorem Ipsum dolor aquicumsitum amet", + "21/04/1998", + "46358570855", + options, + social); + playerRepository.save(player); + } + + @GetMapping("create") + public void setUp(){ + createUser(); + } + @GetMapping("all") + public List retrieveAllProfileData(){ + final var all = playerRepository.findAll(); + return all; + } + @GetMapping + public Optional retrieveProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ + final var profileData = playerRepository.findById(Integer.parseInt(userId)); + return profileData; + } + @PostMapping + public void insertProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId, + @RequestBody final Player player){ + player.setId(Integer.parseInt(userId)); + playerRepository.save(player); + } + @DeleteMapping + public void deleteProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ + final var profileData = playerRepository.findById(Integer.parseInt(userId)); + profileData.get().setId(Integer.parseInt(userId)); + playerRepository.delete(profileData.get()); + } + +} diff --git a/src/main/java/hive/player/entity/Player.java b/src/main/java/hive/player/entity/Player.java new file mode 100644 index 0000000..7553d96 --- /dev/null +++ b/src/main/java/hive/player/entity/Player.java @@ -0,0 +1,76 @@ +package hive.player.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.hibernate.validator.constraints.br.CPF; + +import javax.persistence.*; + +@Entity +@Table(name = "tb_user_profile") +public class Player { + @Id + @JsonIgnore + private Integer id; + + @JsonProperty + @Column(name = "login_alias", unique = true) + private String loginAlias; + @JsonProperty + @Column(name = "email") + private String email; + @JsonProperty + @Column(name = "telnumber") + private String telnumber; + @JsonProperty + @Column(name = "flavor_text") + private String flavorText; + @JsonProperty + @Column(name = "birthday") + private String birthday; + + @JsonProperty + @Column(name = "cpf") + private String cpf; + @Embedded + @JsonProperty + @Column(name = "options") + private PlayerOptions options; + @Embedded + @JsonProperty + @Column(name = "social") + private PlayerSocial social; + + public Player() { + } + + public Integer getId() {//delete by no use? + return id; + } + + public void setId(final Integer id) { + this.id = id; + } + + public Player( + final Integer id, + final String loginAlias, + final String email, + final String telnumber, + final String flavorText, + final String birthday, + final String cpf, + final PlayerOptions options, + final PlayerSocial social + ) { + this.id = id; + this.loginAlias = loginAlias; + this.email = email; + this.telnumber = telnumber; + this.flavorText = flavorText; + this.birthday = birthday; + this.cpf = cpf; + this.options = options; + this.social = social; + } +} diff --git a/src/main/java/hive/player/entity/PlayerOptions.java b/src/main/java/hive/player/entity/PlayerOptions.java new file mode 100644 index 0000000..ec2b4b2 --- /dev/null +++ b/src/main/java/hive/player/entity/PlayerOptions.java @@ -0,0 +1,30 @@ +package hive.player.entity; + +import javax.persistence.Embeddable; + +@Embeddable +public class PlayerOptions { + public String laurel_wreath; + public String honorific; + public String darkmode; + public String notify_hiveshare; + public String notify_hivecentral; + public String notify_disciplines; + + public PlayerOptions( + final String laurel_wreath, + final String honorific, + final String darkmode, + final String notify_hiveshare, + final String notify_hivecentral, + final String notify_disciplines + ) { + this.laurel_wreath = laurel_wreath; + this.honorific = honorific; + this.darkmode = darkmode; + this.notify_hiveshare = notify_hiveshare; + this.notify_hivecentral = notify_hivecentral; + this.notify_disciplines = notify_disciplines; + } + public PlayerOptions(){} +} diff --git a/src/main/java/hive/player/entity/PlayerSocial.java b/src/main/java/hive/player/entity/PlayerSocial.java new file mode 100644 index 0000000..0639b67 --- /dev/null +++ b/src/main/java/hive/player/entity/PlayerSocial.java @@ -0,0 +1,17 @@ +package hive.player.entity; + +import javax.persistence.Embeddable; + +@Embeddable +public class PlayerSocial { + public String github; + public String linkedIn; + public String twitter; + + public PlayerSocial(final String github, final String linkedIn, final String twitter) { + this.github = github; + this.linkedIn = linkedIn; + this.twitter = twitter; + } + public PlayerSocial() {} +} diff --git a/src/main/java/hive/player/repository/PlayerRepository.java b/src/main/java/hive/player/repository/PlayerRepository.java new file mode 100644 index 0000000..ceaa8ae --- /dev/null +++ b/src/main/java/hive/player/repository/PlayerRepository.java @@ -0,0 +1,12 @@ +package hive.player.repository; + +import hive.player.entity.Player; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface PlayerRepository extends JpaRepository { + // @Query("from Player where id= ?1") + // public Player getById(); +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..cdf293e --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,16 @@ +spring.application.name=player-service +server.port=9600 +eureka.client.service-url.default-zone=http://localhost:8761/eureka +# H2 +spring.h2.console.enabled=true +spring.h2.console.path=/h2 +# Datasource +spring.datasource.url=jdbc:h2:file:./db/projeto-pw;AUTO_SERVER=TRUE +spring.datasource.username=sa +spring.datasource.password= +spring.datasource.driver-class-name=org.h2.Driver +spring.jpa.hibernate.ddl-auto=create-drop +#spring.jpa.hibernate.ddl-auto=create +spring.jpa.show-sql=true +spring.jpa.properties.hibernate.format_sql=true +logging.level.org.hibernate.type=trace \ No newline at end of file From 4fec9aca2a8312d7b23f0845f92f76308488c257 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 12 May 2019 02:19:45 -0300 Subject: [PATCH 03/31] Spock REST API Test --- .../controller/PlayerControllerTest.groovy | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/test/groovy/controller/PlayerControllerTest.groovy diff --git a/src/test/groovy/controller/PlayerControllerTest.groovy b/src/test/groovy/controller/PlayerControllerTest.groovy new file mode 100644 index 0000000..a2afb00 --- /dev/null +++ b/src/test/groovy/controller/PlayerControllerTest.groovy @@ -0,0 +1,23 @@ +package controller + +import spock.lang.Specification +import groovyx.net.http.ContentType +import groovyx.net.http.HttpResponseException +import groovyx.net.http.RESTClient +import org.apache.http.HttpResponse +import static hive.pandora.constant.HiveInternalHeaders.* + +class PlayerControllerTest extends Specification { + def urlBase = 'http://localhost:9600/' + def 'Should return success'() { + given:'User exists' + def cliente = new RESTClient("${urlBase}", ContentType.JSON) + when:'When user info is retrieved' + def resposta = cliente.get(headers: ["$AUTHENTICATED_USER_ID": '1']) + then:'HttpStatus Ok is received' + resposta.status == 200 + and: + println() + println resposta.data + } +} From 3f83ce12414c47baf213515ca02484ff9b4e3f2a Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:06:37 -0300 Subject: [PATCH 04/31] Spock REST API Test dependency. --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 0fcfa64..492a8c7 100644 --- a/build.gradle +++ b/build.gradle @@ -42,6 +42,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'com.h2database:h2' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' + implementation 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.1' testImplementation 'org.springframework.boot:spring-boot-starter-test' testCompile( 'org.hamcrest:hamcrest-core:1.3',//if not using delete this From 03d61ba3aca6d2828b869ac5799ab1d1ba6977e0 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:07:38 -0300 Subject: [PATCH 05/31] Added integration tests for the controller. Refactored controller name. --- .../PlayerControllerIntegrationTest.groovy | 142 ++++++++++++++++++ .../controller/PlayerControllerTest.groovy | 23 --- 2 files changed, 142 insertions(+), 23 deletions(-) create mode 100644 src/test/groovy/controller/PlayerControllerIntegrationTest.groovy delete mode 100644 src/test/groovy/controller/PlayerControllerTest.groovy diff --git a/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy b/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy new file mode 100644 index 0000000..afdc965 --- /dev/null +++ b/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy @@ -0,0 +1,142 @@ +package controller + +import hive.player.repository.PlayerRepository +import spock.lang.Specification +import groovyx.net.http.ContentType +import groovyx.net.http.HttpResponseException +import groovyx.net.http.RESTClient +import org.apache.http.HttpResponse +import static hive.pandora.constant.HiveInternalHeaders.* + +/*Integration test. only work with the system up*/ + +class PlayerControllerIntegrationTest extends Specification { + + def urlBase = 'http://localhost:9600/' + def validProfileDataJson = ''' +{ + "loginAlias": "custom2", + "email": "email", + "telnumber": "11985055502", + "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "cpf": "46358570855", + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": "on", + "notify_hiveshare": "on", + "notify_hivecentral": "on", + "notify_disciplines": "on" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } +} + ''' + + /*GET*/ + + def 'Should return success'() { + given: 'User exists' + def client = new RESTClient("${urlBase}", ContentType.JSON) + when: 'When user info is retrieved' + client.handler.failure = { resp, data -> resp.setData(data); return resp } + def response = client.get(headers: ["$AUTHENTICATED_USER_ID": '1']) + then: 'HttpStatus Ok is received' + response.status == 200 + } + + def 'Should return not found'() { + given: 'User does not exists' + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: 'When user info is retrieved' + def response = client.get(headers: ["$AUTHENTICATED_USER_ID": '-1']) + + then: 'HttpStatus not found is received' + response.status == 404 + and: 'Response data null' + response.data == null + } + + def 'Should return server bad request'() { + given: 'User exists' + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: 'When header is wrong' + def response = client.get(headers: ['wrong_key': '1']) + + then: 'HttpStatus server bad request is received' + response.status == 400 + } + /*POST*/ + + def 'Should return success when inserting an user'() { + given: 'Inserted Json is valid' + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: 'When user profile data is inserted' + def response = client.post( + headers: ["$AUTHENTICATED_USER_ID": '1'], + body: "$validProfileDataJson") + + then: 'HttpStatus ok request is received' + response.status == 200 + } + + def 'Should return Bad Request when inserting an empty user'() { + given: 'Inserted Json is valid' + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: 'When user profile data is inserted' + def response = client.post(headers: ["$AUTHENTICATED_USER_ID": '1']) + + then: 'HttpStatus ok request is received' + response.status == 400 + } + + def 'Should Bad Request when inserting an valid user with wrong header key'() { + given: 'Inserted Json is valid' + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: 'When user profile data is inserted' + def response = client.post(headers: ["wrong_key": '1']) + + then: 'HttpStatus ok request is received' + response.status == 400 + } + /*DELETE*/ + + def 'Should return Ok status when inserting an empty user'() { + given: + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: + def response = client.delete(headers: ["$AUTHENTICATED_USER_ID": '1']) + + then: + response.status == 200 + } + + def 'Should Bad Request status when deleting an valid user with wrong header key'() { + given: + def client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + + when: + def response = client.post(headers: ["wrong_key": '1']) + + then: + response.status == 400 + } + +} diff --git a/src/test/groovy/controller/PlayerControllerTest.groovy b/src/test/groovy/controller/PlayerControllerTest.groovy deleted file mode 100644 index a2afb00..0000000 --- a/src/test/groovy/controller/PlayerControllerTest.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package controller - -import spock.lang.Specification -import groovyx.net.http.ContentType -import groovyx.net.http.HttpResponseException -import groovyx.net.http.RESTClient -import org.apache.http.HttpResponse -import static hive.pandora.constant.HiveInternalHeaders.* - -class PlayerControllerTest extends Specification { - def urlBase = 'http://localhost:9600/' - def 'Should return success'() { - given:'User exists' - def cliente = new RESTClient("${urlBase}", ContentType.JSON) - when:'When user info is retrieved' - def resposta = cliente.get(headers: ["$AUTHENTICATED_USER_ID": '1']) - then:'HttpStatus Ok is received' - resposta.status == 200 - and: - println() - println resposta.data - } -} From e1e3a285a31aac230e235c5046ae7c0e8caebea4 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:08:29 -0300 Subject: [PATCH 06/31] Created an spock specification for unit test ( in development ) --- .../PlayerControllerUnitTest.groovy | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/groovy/controller/PlayerControllerUnitTest.groovy diff --git a/src/test/groovy/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/controller/PlayerControllerUnitTest.groovy new file mode 100644 index 0000000..131b57a --- /dev/null +++ b/src/test/groovy/controller/PlayerControllerUnitTest.groovy @@ -0,0 +1,43 @@ +package controller + + +import hive.player.controller.PlayerController +import hive.player.entity.Player +import hive.player.repository.PlayerRepository +import org.mockito.Mock +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.MvcResult +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import spock.lang.Shared +import spock.lang.Specification + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get +import static org.mockito.BDDMockito.given; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import static hive.pandora.constant.HiveInternalHeaders.AUTHENTICATED_USER_ID +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print + +class PlayerControllerUnitTest extends Specification { + + def urlBase = 'http://localhost:9600/' + @Shared Optional player + MockMvc mockMvc + PlayerRepository playerRepository= Mock() + def setup(){ + when: + playerRepository.findById() + then: + player=playerRepository.findById() + } + def "Should add an user"(){ + given: + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController()).build() + expect: + mockMvc.perform(get("$urlBase").header(AUTHENTICATED_USER_ID,1)).andDo(print()) + // mockMvc?.perform(get("$urlBase")?.header(AUTHENTICATED_USER_ID,1))?.andExpect(status().isOk()) + } +} From 9b1330317125c8c92591ab04cd7728ace8d14d25 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:09:08 -0300 Subject: [PATCH 07/31] Repository spock initial experiments --- .../repository/PlayerRepositoryTest.groovy | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/test/groovy/repository/PlayerRepositoryTest.groovy diff --git a/src/test/groovy/repository/PlayerRepositoryTest.groovy b/src/test/groovy/repository/PlayerRepositoryTest.groovy new file mode 100644 index 0000000..b0198fc --- /dev/null +++ b/src/test/groovy/repository/PlayerRepositoryTest.groovy @@ -0,0 +1,50 @@ +package repository + +import hive.player.entity.Player +import hive.player.entity.PlayerOptions +import hive.player.entity.PlayerSocial +import hive.player.repository.PlayerRepository +import org.junit.Before +import org.springframework.beans.factory.annotation.Autowired +import spock.lang.Shared +import spock.lang.Specification + +class PlayerRepositoryTest extends Specification{ + @Shared + Player player + + @Shared + PlayerRepository playerRepository + + def setup(){ + def social=new PlayerSocial() + def options = new PlayerOptions( + "ouro", + "titan do café", + "on", + "on", + "on", + "on") + player=new Player( + 1, + "alias", + "email", + "11985054202", + "String grande", + "21/04/1998", + "46358570855", + options, + social) + playerRepository.save(player) + } + + def 'Test User Creation'(){ + given:'dado' + def mina='Jennifer' + def persistedPlayer=playerRepository.getOne 1 + when:'quando' + def frase="O nome dela é $mina" + then:'então' + player==persistedPlayer + } +} From 0db96fe6c27f0d2a6a2bf73318c541c70338379c Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:25:17 -0300 Subject: [PATCH 08/31] Pandora added --- pandora | 1 + 1 file changed, 1 insertion(+) create mode 160000 pandora diff --git a/pandora b/pandora new file mode 160000 index 0000000..1d677c4 --- /dev/null +++ b/pandora @@ -0,0 +1 @@ +Subproject commit 1d677c43f5dc204545eb66de763f9ea4c84382de From 0d5be6037057f5819f4188d8dfbf53e37254db92 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 13 May 2019 00:57:49 -0300 Subject: [PATCH 09/31] Unit test under experimentation --- .../PlayerControllerUnitTest.groovy | 30 +++++++++++++++---- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/test/groovy/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/controller/PlayerControllerUnitTest.groovy index 131b57a..856ee3f 100644 --- a/src/test/groovy/controller/PlayerControllerUnitTest.groovy +++ b/src/test/groovy/controller/PlayerControllerUnitTest.groovy @@ -3,8 +3,11 @@ package controller import hive.player.controller.PlayerController import hive.player.entity.Player +import hive.player.entity.PlayerOptions +import hive.player.entity.PlayerSocial import hive.player.repository.PlayerRepository import org.mockito.Mock +import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.MvcResult import org.springframework.test.web.servlet.setup.MockMvcBuilders @@ -24,20 +27,35 @@ import static org.springframework.test.web.servlet.result.MockMvcResultHandlers. class PlayerControllerUnitTest extends Specification { def urlBase = 'http://localhost:9600/' - @Shared Optional player + @Shared Player player MockMvc mockMvc PlayerRepository playerRepository= Mock() def setup(){ - when: - playerRepository.findById() - then: - player=playerRepository.findById() + player=new Player( + 1, + "alias", + "email", + "11985054202", + "String grande", + "21/04/1998", + "46358570855", + new PlayerOptions( + "ouro", + "titan do café", + "on", + "on", + "on", + "on"), + new PlayerSocial("git","linkedin","@twitter")) } def "Should add an user"(){ given: mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController()).build() + and: + playerRepository.findById(1) >> player expect: - mockMvc.perform(get("$urlBase").header(AUTHENTICATED_USER_ID,1)).andDo(print()) +// mockMvc?.perform(get("$urlBase/create")).andDo(print()) + mockMvc?.perform(get("$urlBase").header(AUTHENTICATED_USER_ID,1)).andDo(print()) // mockMvc?.perform(get("$urlBase")?.header(AUTHENTICATED_USER_ID,1))?.andExpect(status().isOk()) } } From fdcff1928bd0867071baecfa21d43339b086e1ca Mon Sep 17 00:00:00 2001 From: anabneri Date: Mon, 13 May 2019 21:16:57 -0300 Subject: [PATCH 10/31] refactored ids --- src/main/java/hive/player/entity/Player.java | 35 +++++++++++--------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/main/java/hive/player/entity/Player.java b/src/main/java/hive/player/entity/Player.java index 7553d96..9b29b61 100644 --- a/src/main/java/hive/player/entity/Player.java +++ b/src/main/java/hive/player/entity/Player.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import org.hibernate.validator.constraints.br.CPF; import javax.persistence.*; @@ -11,7 +10,10 @@ public class Player { @Id @JsonIgnore - private Integer id; + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer playerId; + @JsonIgnore + private String autenticateUserId; @JsonProperty @Column(name = "login_alias", unique = true) @@ -29,9 +31,6 @@ public class Player { @Column(name = "birthday") private String birthday; - @JsonProperty - @Column(name = "cpf") - private String cpf; @Embedded @JsonProperty @Column(name = "options") @@ -44,32 +43,38 @@ public class Player { public Player() { } - public Integer getId() {//delete by no use? - return id; + public Integer getPlayerId() { + return playerId; + } + + public void setPlayerId(Integer playerId) { + this.playerId = playerId; + } + + public String getAutenticateUserId() { + return autenticateUserId; } - public void setId(final Integer id) { - this.id = id; + public void setAutenticateUserId(String autenticateUserId) { + this.autenticateUserId = autenticateUserId; } public Player( - final Integer id, + final String autenticateUserId, final String loginAlias, final String email, - final String telnumber, + final String telNumber, final String flavorText, final String birthday, - final String cpf, final PlayerOptions options, final PlayerSocial social ) { - this.id = id; + this.autenticateUserId = autenticateUserId; this.loginAlias = loginAlias; this.email = email; - this.telnumber = telnumber; + this.telnumber = telNumber; this.flavorText = flavorText; this.birthday = birthday; - this.cpf = cpf; this.options = options; this.social = social; } From b0eaadd0c97417e743f112cc51c8789b6d1d06e4 Mon Sep 17 00:00:00 2001 From: anabneri Date: Mon, 13 May 2019 21:18:16 -0300 Subject: [PATCH 11/31] deleted DELETE method --- .../player/controller/PlayerController.java | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/main/java/hive/player/controller/PlayerController.java b/src/main/java/hive/player/controller/PlayerController.java index 9906c1c..9b71438 100644 --- a/src/main/java/hive/player/controller/PlayerController.java +++ b/src/main/java/hive/player/controller/PlayerController.java @@ -2,26 +2,24 @@ import static hive.pandora.constant.HiveInternalHeaders.*; -import com.netflix.client.http.HttpResponse; import hive.player.entity.Player; import hive.player.entity.PlayerOptions; import hive.player.entity.PlayerSocial; import hive.player.repository.PlayerRepository; -import org.apache.coyote.Response; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.io.Resource; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; -import java.util.Optional; @RestController @RequestMapping("/") public class PlayerController { - @Autowired PlayerRepository playerRepository; + private final PlayerRepository playerRepository; + @Autowired + public PlayerController(PlayerRepository playerRepository){ + this.playerRepository=playerRepository; + } public void createUser(){ var social=new PlayerSocial("git","linkedin","@twitter"); var options = new PlayerOptions( @@ -32,24 +30,22 @@ public void createUser(){ "on", "on"); var player=new Player( - 1, + "1", "alias", "email", "11985054202", "String grande", "21/04/1998", - "46358570855", options, social); playerRepository.save(player); player=new Player( - 2, + "2", "germano", "email", "11985055502", "String grande Lorem Ipsum dolor aquicumsitum amet", "21/04/1998", - "46358570855", options, social); playerRepository.save(player); @@ -59,27 +55,30 @@ public void createUser(){ public void setUp(){ createUser(); } + @GetMapping("all") public List retrieveAllProfileData(){ final var all = playerRepository.findAll(); return all; } + @GetMapping - public Optional retrieveProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ - final var profileData = playerRepository.findById(Integer.parseInt(userId)); - return profileData; + public Player retrieveProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ + var player = playerRepository.getByAutenticateUserId(userId); + if(player==null){ + player=new Player(); + player.setAutenticateUserId(userId); + playerRepository.save(player); + } + return player; } + @PostMapping public void insertProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId, @RequestBody final Player player){ - player.setId(Integer.parseInt(userId)); + player.setPlayerId(playerRepository.getPlayerIdWithAutenticateUserId(userId)); + player.setAutenticateUserId(userId); playerRepository.save(player); } - @DeleteMapping - public void deleteProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ - final var profileData = playerRepository.findById(Integer.parseInt(userId)); - profileData.get().setId(Integer.parseInt(userId)); - playerRepository.delete(profileData.get()); - } } From fe5da53b812e3f59a7dfc0452e3e6fbcee0cdcf9 Mon Sep 17 00:00:00 2001 From: anabneri Date: Mon, 13 May 2019 21:18:30 -0300 Subject: [PATCH 12/31] refactored JPQL --- .../java/hive/player/repository/PlayerRepository.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/hive/player/repository/PlayerRepository.java b/src/main/java/hive/player/repository/PlayerRepository.java index ceaa8ae..ad29a8e 100644 --- a/src/main/java/hive/player/repository/PlayerRepository.java +++ b/src/main/java/hive/player/repository/PlayerRepository.java @@ -7,6 +7,11 @@ @Repository public interface PlayerRepository extends JpaRepository { - // @Query("from Player where id= ?1") - // public Player getById(); + + @Query("from Player where autenticateUserId= ?1") + Player getByAutenticateUserId(String autenticateUserId); + + @Query("select playerId from Player where autenticateUserId= ?1") + Integer getPlayerIdWithAutenticateUserId(String autenticateUserId); + } From e90dca81988676917ea99d74738d61ec3deab7c7 Mon Sep 17 00:00:00 2001 From: anabneri Date: Mon, 13 May 2019 21:19:11 -0300 Subject: [PATCH 13/31] refactored tests --- .../PlayerControllerIntegrationTest.groovy | 54 +------- .../PlayerControllerUnitTest.groovy | 130 ++++++++++++++---- 2 files changed, 111 insertions(+), 73 deletions(-) diff --git a/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy b/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy index afdc965..91391fe 100644 --- a/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy +++ b/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy @@ -20,7 +20,6 @@ class PlayerControllerIntegrationTest extends Specification { "telnumber": "11985055502", "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", "birthday": "21/04/1998", - "cpf": "46358570855", "options": { "laurel_wreath": "ouro", "honorific": "titan do café", @@ -39,31 +38,19 @@ class PlayerControllerIntegrationTest extends Specification { /*GET*/ - def 'Should return success'() { + def 'Should GET user successfully'() { given: 'User exists' def client = new RESTClient("${urlBase}", ContentType.JSON) + when: 'When user info is retrieved' client.handler.failure = { resp, data -> resp.setData(data); return resp } def response = client.get(headers: ["$AUTHENTICATED_USER_ID": '1']) + then: 'HttpStatus Ok is received' response.status == 200 } - def 'Should return not found'() { - given: 'User does not exists' - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: 'When user info is retrieved' - def response = client.get(headers: ["$AUTHENTICATED_USER_ID": '-1']) - - then: 'HttpStatus not found is received' - response.status == 404 - and: 'Response data null' - response.data == null - } - - def 'Should return server bad request'() { + def 'Should return server bad request when header is wrong'() { given: 'User exists' def client = new RESTClient("${urlBase}", ContentType.JSON) client.handler.failure = { resp, data -> resp.setData(data); return resp } @@ -74,9 +61,8 @@ class PlayerControllerIntegrationTest extends Specification { then: 'HttpStatus server bad request is received' response.status == 400 } - /*POST*/ - def 'Should return success when inserting an user'() { + def 'Should POST an user successfully'() { given: 'Inserted Json is valid' def client = new RESTClient("${urlBase}", ContentType.JSON) client.handler.failure = { resp, data -> resp.setData(data); return resp } @@ -90,7 +76,7 @@ class PlayerControllerIntegrationTest extends Specification { response.status == 200 } - def 'Should return Bad Request when inserting an empty user'() { + def 'Should return Bad Request when POST an empty profile data'() { given: 'Inserted Json is valid' def client = new RESTClient("${urlBase}", ContentType.JSON) client.handler.failure = { resp, data -> resp.setData(data); return resp } @@ -102,7 +88,7 @@ class PlayerControllerIntegrationTest extends Specification { response.status == 400 } - def 'Should Bad Request when inserting an valid user with wrong header key'() { + def 'Should Bad Request when POST an profile data with wrong header key'() { given: 'Inserted Json is valid' def client = new RESTClient("${urlBase}", ContentType.JSON) client.handler.failure = { resp, data -> resp.setData(data); return resp } @@ -113,30 +99,4 @@ class PlayerControllerIntegrationTest extends Specification { then: 'HttpStatus ok request is received' response.status == 400 } - /*DELETE*/ - - def 'Should return Ok status when inserting an empty user'() { - given: - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: - def response = client.delete(headers: ["$AUTHENTICATED_USER_ID": '1']) - - then: - response.status == 200 - } - - def 'Should Bad Request status when deleting an valid user with wrong header key'() { - given: - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: - def response = client.post(headers: ["wrong_key": '1']) - - then: - response.status == 400 - } - } diff --git a/src/test/groovy/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/controller/PlayerControllerUnitTest.groovy index 856ee3f..59d1042 100644 --- a/src/test/groovy/controller/PlayerControllerUnitTest.groovy +++ b/src/test/groovy/controller/PlayerControllerUnitTest.groovy @@ -1,6 +1,5 @@ package controller - import hive.player.controller.PlayerController import hive.player.entity.Player import hive.player.entity.PlayerOptions @@ -10,6 +9,7 @@ import org.mockito.Mock import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.MvcResult +import org.springframework.test.web.servlet.ResultMatcher import org.springframework.test.web.servlet.setup.MockMvcBuilders import spock.lang.Shared import spock.lang.Specification @@ -30,32 +30,110 @@ class PlayerControllerUnitTest extends Specification { @Shared Player player MockMvc mockMvc PlayerRepository playerRepository= Mock() + def invalidProfileDataJson='{"invalid_key":"value"}' + def validProfileDataJson = ''' +{ + "loginAlias": "custom2", + "email": "email", + "telnumber": "11985055502", + "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": "on", + "notify_hiveshare": "on", + "notify_hivecentral": "on", + "notify_disciplines": "on" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } +} + ''' def setup(){ - player=new Player( - 1, - "alias", - "email", - "11985054202", - "String grande", - "21/04/1998", - "46358570855", - new PlayerOptions( - "ouro", - "titan do café", - "on", - "on", - "on", - "on"), - new PlayerSocial("git","linkedin","@twitter")) } - def "Should add an user"(){ - given: - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController()).build() - and: - playerRepository.findById(1) >> player - expect: -// mockMvc?.perform(get("$urlBase/create")).andDo(print()) - mockMvc?.perform(get("$urlBase").header(AUTHENTICATED_USER_ID,1)).andDo(print()) - // mockMvc?.perform(get("$urlBase")?.header(AUTHENTICATED_USER_ID,1))?.andExpect(status().isOk()) + + def "Should GET profile data successfully"(){ + + given:"Correct header" + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + expect:"Success when GET" + mockMvc.perform(get("$urlBase") + .header(AUTHENTICATED_USER_ID,val)) + .andExpect(status().isOk()) + + where:"numbers or string as header value" + val | _ + 1 | _ + "2" | _ + + } + + def "Should POST profile data successfully"(){ + + given:"Correct header" + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + expect:"Success when POST" + mockMvc.perform(post("$urlBase") + .header(AUTHENTICATED_USER_ID,val) + .contentType('application/json') + .content(validProfileDataJson)) + .andExpect(status().isOk()) + + where:"numbers or string as header value" + val | _ + 1 | _ + "2" | _ + } + def "Should not accept GET profile data"(){ + + given:"Wrong header" + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + when:"status NotAcceptable when GET" + def response=mockMvc.perform(get("$urlBase") + .header(key,1)) + .andExpect(status().isNotAcceptable()) + println response + + then: +// response.andExpect(status().is(400)) + thrown IllegalArgumentException + + where:"Wrong or empty key" + key | _ + "" | _ + " " | _ + null| _ + + } + + def "Should not accept POST profile data"(){ + + given:"Wrong header" + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + when:"status NotAcceptable when POST" + def response=mockMvc.perform(post("$urlBase") + .header(key,1) + .contentType('application/json') + .content(validProfileDataJson)) + println response + + then: +// response.andExpect(status().is(400)) + thrown IllegalArgumentException + + where:"Wrong or empty key" + key | _ + "" | _ + " " | _ + null| _ + } } From 461a4089e5853eda70f1cc297d6fb322fe7576d0 Mon Sep 17 00:00:00 2001 From: anabneri Date: Tue, 14 May 2019 21:32:41 -0300 Subject: [PATCH 14/31] New specifications --- .../PlayerControllerUnitTest.groovy | 93 +++++++++++++------ 1 file changed, 67 insertions(+), 26 deletions(-) diff --git a/src/test/groovy/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/controller/PlayerControllerUnitTest.groovy index 59d1042..c1a2554 100644 --- a/src/test/groovy/controller/PlayerControllerUnitTest.groovy +++ b/src/test/groovy/controller/PlayerControllerUnitTest.groovy @@ -61,10 +61,13 @@ class PlayerControllerUnitTest extends Specification { given:"Correct header" mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - expect:"Success when GET" - mockMvc.perform(get("$urlBase") + when:"Success when GET" + def response=mockMvc.perform(get("$urlBase") .header(AUTHENTICATED_USER_ID,val)) - .andExpect(status().isOk()) + .andReturn() + .getResponse() + then: + response.getStatus()==200 where:"numbers or string as header value" val | _ @@ -78,61 +81,99 @@ class PlayerControllerUnitTest extends Specification { given:"Correct header" mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - expect:"Success when POST" - mockMvc.perform(post("$urlBase") + when:"Success when POST" + def response=mockMvc.perform(post("$urlBase") .header(AUTHENTICATED_USER_ID,val) .contentType('application/json') .content(validProfileDataJson)) - .andExpect(status().isOk()) + .andReturn().getResponse() + then: + response.getStatus()==200 where:"numbers or string as header value" val | _ 1 | _ "2" | _ + } - def "Should not accept GET profile data"(){ + def "Should AAAAA when GET"(){ - given:"Wrong header" + given: + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + when: + def response=mockMvc.perform(get("$urlBase") + .header(key,val)).andReturn().getResponse() + println response.getStatus() + + then: + response.getStatus()==400 + + where:" wrong key on header with blank or filled value" + key | val | _ + "wrong key" | "something"| _ + "wrong_key" | " " | _ + + } + def "Should AAAAA when POST"(){ + + given: mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - when:"status NotAcceptable when GET" + when: def response=mockMvc.perform(get("$urlBase") - .header(key,1)) - .andExpect(status().isNotAcceptable()) - println response + .header(key,val)).andReturn().getResponse() + println response.getStatus() + + then:"" + response.getStatus()==400 + + where:" wrong key on header with blank or filled value" + key | val | _ + "wrong key" | "something"| _ + "wrong_key" | " " | _ + + } + + def "Should give illegal argument GET profile data"(){ + + given:"Wrong header" + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + + when:"GET with header key as #key" + mockMvc.perform(get("$urlBase") + .header(key,val)).andReturn() then: -// response.andExpect(status().is(400)) thrown IllegalArgumentException - where:"Wrong or empty key" - key | _ - "" | _ - " " | _ - null| _ + + where:"empty or null key" + key | val | _ + AUTHENTICATED_USER_ID | null | _ + null | "something"| _ + "" | "something"| _ + "" | null | _ } - def "Should not accept POST profile data"(){ + def "Should give illegal argument POST profile data"(){ given:"Wrong header" mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - when:"status NotAcceptable when POST" - def response=mockMvc.perform(post("$urlBase") + when:"POST with header key as #key" + mockMvc.perform(post("$urlBase") .header(key,1) .contentType('application/json') - .content(validProfileDataJson)) - println response + .content(validProfileDataJson)).andReturn() then: -// response.andExpect(status().is(400)) thrown IllegalArgumentException - where:"Wrong or empty key" + where:"empty or null key" key | _ "" | _ - " " | _ null| _ } From b54f36c38c4ee999ebb5b82cfa700d43154e1561 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 19 May 2019 23:55:13 -0300 Subject: [PATCH 15/31] Extracted methods and deleted experimental methods --- .../player/controller/PlayerController.java | 90 +++++++------------ 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/src/main/java/hive/player/controller/PlayerController.java b/src/main/java/hive/player/controller/PlayerController.java index 9b71438..ec6c5a7 100644 --- a/src/main/java/hive/player/controller/PlayerController.java +++ b/src/main/java/hive/player/controller/PlayerController.java @@ -3,82 +3,58 @@ import static hive.pandora.constant.HiveInternalHeaders.*; import hive.player.entity.Player; -import hive.player.entity.PlayerOptions; -import hive.player.entity.PlayerSocial; +import hive.player.exception.PlayerIdShouldNotBeInJsonException; import hive.player.repository.PlayerRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; -import java.util.List; - @RestController @RequestMapping("/") public class PlayerController { - private final PlayerRepository playerRepository; + @Autowired - public PlayerController(PlayerRepository playerRepository){ - this.playerRepository=playerRepository; - } - public void createUser(){ - var social=new PlayerSocial("git","linkedin","@twitter"); - var options = new PlayerOptions( - "ouro", - "titan do café", - "on", - "on", - "on", - "on"); - var player=new Player( - "1", - "alias", - "email", - "11985054202", - "String grande", - "21/04/1998", - options, - social); - playerRepository.save(player); - player=new Player( - "2", - "germano", - "email", - "11985055502", - "String grande Lorem Ipsum dolor aquicumsitum amet", - "21/04/1998", - options, - social); - playerRepository.save(player); + public PlayerController(final PlayerRepository playerRepository) { + this.playerRepository = playerRepository; } - @GetMapping("create") - public void setUp(){ - createUser(); + @GetMapping + public Player retrieveProfileData( + @RequestHeader(name = AUTHENTICATED_USER_ID) final String authenticatedUserId + ) { + return createAnPlayerInDatabaseIfNotExists(authenticatedUserId); } - @GetMapping("all") - public List retrieveAllProfileData(){ - final var all = playerRepository.findAll(); - return all; + @PostMapping + public void insertProfileData( + @RequestHeader(name = AUTHENTICATED_USER_ID) final String authenticatedUserId, + @RequestBody final Player player + ) { + if(player.getPlayerId()!=null){ + throw new PlayerIdShouldNotBeInJsonException(); + } + updatePlayerCorrelatedWithTheAuthenticatedId(player, authenticatedUserId); + player.setAuthenticatedUserId(authenticatedUserId); + playerRepository.save(player); } - @GetMapping - public Player retrieveProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId){ - var player = playerRepository.getByAutenticateUserId(userId); - if(player==null){ - player=new Player(); - player.setAutenticateUserId(userId); + private Player createAnPlayerInDatabaseIfNotExists(final String authenticatedUserId) { + var player = playerRepository.findByAuthenticatedUserId(authenticatedUserId); + if (player == null) { + player = new Player(authenticatedUserId); playerRepository.save(player); } return player; } - @PostMapping - public void insertProfileData(@RequestHeader(name=AUTHENTICATED_USER_ID) final String userId, - @RequestBody final Player player){ - player.setPlayerId(playerRepository.getPlayerIdWithAutenticateUserId(userId)); - player.setAutenticateUserId(userId); - playerRepository.save(player); + private void updatePlayerCorrelatedWithTheAuthenticatedId( + final Player player, + final String authenticatedUserId + ) { + final var autogeneratedPlayerId = + playerRepository.findPlayerIdWithAuthenticatedUserId(authenticatedUserId); + if (autogeneratedPlayerId != null) { + player.setPlayerId(autogeneratedPlayerId); + } } - } From debc9a14e30906ceefa82be98f24f67a1bacb2e3 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 19 May 2019 23:56:36 -0300 Subject: [PATCH 16/31] Added exception for blank authenticatedUserId --- src/main/java/hive/player/entity/Player.java | 25 +++++++++++++------ .../player/exception/BlankIdException.java | 8 ++++++ 2 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 src/main/java/hive/player/exception/BlankIdException.java diff --git a/src/main/java/hive/player/entity/Player.java b/src/main/java/hive/player/entity/Player.java index 9b29b61..9f282ef 100644 --- a/src/main/java/hive/player/entity/Player.java +++ b/src/main/java/hive/player/entity/Player.java @@ -2,8 +2,10 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import hive.player.exception.BlankIdException; import javax.persistence.*; +import javax.validation.constraints.NotNull; @Entity @Table(name = "tb_user_profile") @@ -11,9 +13,10 @@ public class Player { @Id @JsonIgnore @GeneratedValue(strategy = GenerationType.IDENTITY) + //is some DBMS like Oracle you should change the strategy private Integer playerId; @JsonIgnore - private String autenticateUserId; + private String authenticatedUserId; @JsonProperty @Column(name = "login_alias", unique = true) @@ -40,7 +43,7 @@ public class Player { @Column(name = "social") private PlayerSocial social; - public Player() { + private Player() { } public Integer getPlayerId() { @@ -51,16 +54,19 @@ public void setPlayerId(Integer playerId) { this.playerId = playerId; } - public String getAutenticateUserId() { - return autenticateUserId; + public String getAuthenticatedUserId() { + return authenticatedUserId; } - public void setAutenticateUserId(String autenticateUserId) { - this.autenticateUserId = autenticateUserId; + public void setAuthenticatedUserId(@NotNull String authenticatedUserId) { + if(authenticatedUserId.isBlank()){ + throw new BlankIdException(); + } + this.authenticatedUserId = authenticatedUserId; } public Player( - final String autenticateUserId, + @NotNull final String authenticatedUserId, final String loginAlias, final String email, final String telNumber, @@ -69,7 +75,7 @@ public Player( final PlayerOptions options, final PlayerSocial social ) { - this.autenticateUserId = autenticateUserId; + setAuthenticatedUserId(authenticatedUserId); this.loginAlias = loginAlias; this.email = email; this.telnumber = telNumber; @@ -78,4 +84,7 @@ public Player( this.options = options; this.social = social; } + public Player(@NotNull final String authenticatedUserId){ + setAuthenticatedUserId(authenticatedUserId); + } } diff --git a/src/main/java/hive/player/exception/BlankIdException.java b/src/main/java/hive/player/exception/BlankIdException.java new file mode 100644 index 0000000..93abe73 --- /dev/null +++ b/src/main/java/hive/player/exception/BlankIdException.java @@ -0,0 +1,8 @@ +package hive.player.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "The Authenticated user id can not be blank") +public class BlankIdException extends RuntimeException{ +} From 3411b936c1237ac5b1355ec3b2dfd3482b6a222e Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 19 May 2019 23:58:06 -0300 Subject: [PATCH 17/31] Added restriction exception for the Json in POST requests --- .../exception/PlayerIdShouldNotBeInJsonException.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/hive/player/exception/PlayerIdShouldNotBeInJsonException.java diff --git a/src/main/java/hive/player/exception/PlayerIdShouldNotBeInJsonException.java b/src/main/java/hive/player/exception/PlayerIdShouldNotBeInJsonException.java new file mode 100644 index 0000000..dfa1a1a --- /dev/null +++ b/src/main/java/hive/player/exception/PlayerIdShouldNotBeInJsonException.java @@ -0,0 +1,8 @@ +package hive.player.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(code = HttpStatus.BAD_REQUEST, reason = "The autogenerated playerId should not be in JSON") +public class PlayerIdShouldNotBeInJsonException extends RuntimeException{ +} From f59e53203cf6c640b0896ef08b42e4c246264feb Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 19 May 2019 23:59:30 -0300 Subject: [PATCH 18/31] Refactored spock tests --- .../PlayerControllerIntegrationTest.groovy | 102 --------- .../PlayerControllerUnitTest.groovy | 180 ---------------- .../PlayerControllerIntegrationTest.groovy | 121 +++++++++++ .../PlayerControllerUnitTest.groovy | 203 ++++++++++++++++++ 4 files changed, 324 insertions(+), 282 deletions(-) delete mode 100644 src/test/groovy/controller/PlayerControllerIntegrationTest.groovy delete mode 100644 src/test/groovy/controller/PlayerControllerUnitTest.groovy create mode 100644 src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy create mode 100644 src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy diff --git a/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy b/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy deleted file mode 100644 index 91391fe..0000000 --- a/src/test/groovy/controller/PlayerControllerIntegrationTest.groovy +++ /dev/null @@ -1,102 +0,0 @@ -package controller - -import hive.player.repository.PlayerRepository -import spock.lang.Specification -import groovyx.net.http.ContentType -import groovyx.net.http.HttpResponseException -import groovyx.net.http.RESTClient -import org.apache.http.HttpResponse -import static hive.pandora.constant.HiveInternalHeaders.* - -/*Integration test. only work with the system up*/ - -class PlayerControllerIntegrationTest extends Specification { - - def urlBase = 'http://localhost:9600/' - def validProfileDataJson = ''' -{ - "loginAlias": "custom2", - "email": "email", - "telnumber": "11985055502", - "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", - "birthday": "21/04/1998", - "options": { - "laurel_wreath": "ouro", - "honorific": "titan do café", - "darkmode": "on", - "notify_hiveshare": "on", - "notify_hivecentral": "on", - "notify_disciplines": "on" - }, - "social": { - "github": "git", - "linkedIn": "linkedin", - "twitter": "@twitter" - } -} - ''' - - /*GET*/ - - def 'Should GET user successfully'() { - given: 'User exists' - def client = new RESTClient("${urlBase}", ContentType.JSON) - - when: 'When user info is retrieved' - client.handler.failure = { resp, data -> resp.setData(data); return resp } - def response = client.get(headers: ["$AUTHENTICATED_USER_ID": '1']) - - then: 'HttpStatus Ok is received' - response.status == 200 - } - - def 'Should return server bad request when header is wrong'() { - given: 'User exists' - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: 'When header is wrong' - def response = client.get(headers: ['wrong_key': '1']) - - then: 'HttpStatus server bad request is received' - response.status == 400 - } - - def 'Should POST an user successfully'() { - given: 'Inserted Json is valid' - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: 'When user profile data is inserted' - def response = client.post( - headers: ["$AUTHENTICATED_USER_ID": '1'], - body: "$validProfileDataJson") - - then: 'HttpStatus ok request is received' - response.status == 200 - } - - def 'Should return Bad Request when POST an empty profile data'() { - given: 'Inserted Json is valid' - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: 'When user profile data is inserted' - def response = client.post(headers: ["$AUTHENTICATED_USER_ID": '1']) - - then: 'HttpStatus ok request is received' - response.status == 400 - } - - def 'Should Bad Request when POST an profile data with wrong header key'() { - given: 'Inserted Json is valid' - def client = new RESTClient("${urlBase}", ContentType.JSON) - client.handler.failure = { resp, data -> resp.setData(data); return resp } - - when: 'When user profile data is inserted' - def response = client.post(headers: ["wrong_key": '1']) - - then: 'HttpStatus ok request is received' - response.status == 400 - } -} diff --git a/src/test/groovy/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/controller/PlayerControllerUnitTest.groovy deleted file mode 100644 index c1a2554..0000000 --- a/src/test/groovy/controller/PlayerControllerUnitTest.groovy +++ /dev/null @@ -1,180 +0,0 @@ -package controller - -import hive.player.controller.PlayerController -import hive.player.entity.Player -import hive.player.entity.PlayerOptions -import hive.player.entity.PlayerSocial -import hive.player.repository.PlayerRepository -import org.mockito.Mock -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.MvcResult -import org.springframework.test.web.servlet.ResultMatcher -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import spock.lang.Shared -import spock.lang.Specification - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get -import static org.mockito.BDDMockito.given; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import static hive.pandora.constant.HiveInternalHeaders.AUTHENTICATED_USER_ID -import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print - -class PlayerControllerUnitTest extends Specification { - - def urlBase = 'http://localhost:9600/' - @Shared Player player - MockMvc mockMvc - PlayerRepository playerRepository= Mock() - def invalidProfileDataJson='{"invalid_key":"value"}' - def validProfileDataJson = ''' -{ - "loginAlias": "custom2", - "email": "email", - "telnumber": "11985055502", - "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", - "birthday": "21/04/1998", - "options": { - "laurel_wreath": "ouro", - "honorific": "titan do café", - "darkmode": "on", - "notify_hiveshare": "on", - "notify_hivecentral": "on", - "notify_disciplines": "on" - }, - "social": { - "github": "git", - "linkedIn": "linkedin", - "twitter": "@twitter" - } -} - ''' - def setup(){ - } - - def "Should GET profile data successfully"(){ - - given:"Correct header" - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when:"Success when GET" - def response=mockMvc.perform(get("$urlBase") - .header(AUTHENTICATED_USER_ID,val)) - .andReturn() - .getResponse() - then: - response.getStatus()==200 - - where:"numbers or string as header value" - val | _ - 1 | _ - "2" | _ - - } - - def "Should POST profile data successfully"(){ - - given:"Correct header" - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when:"Success when POST" - def response=mockMvc.perform(post("$urlBase") - .header(AUTHENTICATED_USER_ID,val) - .contentType('application/json') - .content(validProfileDataJson)) - .andReturn().getResponse() - then: - response.getStatus()==200 - - where:"numbers or string as header value" - val | _ - 1 | _ - "2" | _ - - } - def "Should AAAAA when GET"(){ - - given: - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when: - def response=mockMvc.perform(get("$urlBase") - .header(key,val)).andReturn().getResponse() - println response.getStatus() - - then: - response.getStatus()==400 - - where:" wrong key on header with blank or filled value" - key | val | _ - "wrong key" | "something"| _ - "wrong_key" | " " | _ - - } - def "Should AAAAA when POST"(){ - - given: - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when: - def response=mockMvc.perform(get("$urlBase") - .header(key,val)).andReturn().getResponse() - println response.getStatus() - - then:"" - response.getStatus()==400 - - where:" wrong key on header with blank or filled value" - key | val | _ - "wrong key" | "something"| _ - "wrong_key" | " " | _ - - } - - def "Should give illegal argument GET profile data"(){ - - given:"Wrong header" - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when:"GET with header key as #key" - mockMvc.perform(get("$urlBase") - .header(key,val)).andReturn() - - then: - thrown IllegalArgumentException - - - where:"empty or null key" - key | val | _ - AUTHENTICATED_USER_ID | null | _ - null | "something"| _ - "" | "something"| _ - "" | null | _ - - } - - def "Should give illegal argument POST profile data"(){ - - given:"Wrong header" - mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() - - when:"POST with header key as #key" - mockMvc.perform(post("$urlBase") - .header(key,1) - .contentType('application/json') - .content(validProfileDataJson)).andReturn() - - then: - thrown IllegalArgumentException - - where:"empty or null key" - key | _ - "" | _ - null| _ - - } -} diff --git a/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy b/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy new file mode 100644 index 0000000..7e9b4c4 --- /dev/null +++ b/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy @@ -0,0 +1,121 @@ +package hive.player.controller + +import hive.player.repository.PlayerRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest +import spock.lang.Shared +import spock.lang.Specification +import groovyx.net.http.ContentType +import groovyx.net.http.RESTClient + +import static hive.pandora.constant.HiveInternalHeaders.* + +/*Integration test. only work with the system up*/ +class PlayerControllerIntegrationTest extends Specification { + + @Shared + def integrationTestHeaderValue="INTEGRATION" + @Shared + RESTClient client + + def setup(){ + client = new RESTClient("${urlBase}", ContentType.JSON) + client.handler.failure = { resp, data -> resp.setData(data); return resp } + } + + def urlBase = 'http://localhost:9600/' + + def validProfileDataJson = ''' +{ + "loginAlias": "Integration_Test", + "email": "integration@test.com", + "telnumber": "11987654321", + "flavorText": "Large string Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "options": { + "laurel_wreath": "CHALLENGER", + "honorific": "Coffee Titan", + "darkmode": "on", + "notify_hiveshare": "on", + "notify_hivecentral": "on", + "notify_disciplines": "on" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } +} + ''' + + def cleanupSpec(){ + //should have some delete method in the original application + } + + def 'Should GET user successfully'() { + + given: 'perform GET with correct header' + def response = client.get( + headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"]) + + expect: 'HttpStatus OK' + response.status == 200 + } + + def 'Should POST an user successfully'() { + + given: 'perform POST with valid Json' + def response = client.post( + headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"], + body: "$validProfileDataJson") + + expect: 'HttpStatus OK' + response.status == 200 + } + + def 'Should return BAD REQUEST when GET with wrong Header key'() { + + given: 'perform GET with wrong Header key' + def response = client.get( + headers: ['wrong_key': "${integrationTestHeaderValue}"]) + + expect: 'HttpStatus BAD REQUEST' + response.status == 400 + } + + def 'Should return BAD REQUEST when POST with wrong Header key'() { + + given: 'perform POST with wrong Header key' + def response = client.post( + headers: ["wrong_key": '1']) + + expect: 'HttpStatus BAD REQUEST' + response.status == 400 + } + + def 'Should return BAD REQUEST when POST with an empty body request'() { + + given: 'perform POST with empty body request' + def response = client.post( + headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"]) + + expect: 'HttpStatus BAD REQUEST' + response.status == 400 + } + + def 'Should return BAD REQUEST when POST a body request with PlayerId'() { + + given: 'Json containing playerId as Header key' + def invalidProfileDataJson='{"playerId": 10}' + + when: 'When user profile data is inserted' + def response = client.post( + headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"], + body: ["$invalidProfileDataJson"]) + + + then: 'HttpStatus ok request is received' + response.status == 400 + } + +} diff --git a/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy new file mode 100644 index 0000000..37e2990 --- /dev/null +++ b/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy @@ -0,0 +1,203 @@ +package hive.player.controller + + +import hive.player.entity.Player +import hive.player.entity.PlayerOptions +import hive.player.repository.PlayerRepository +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import spock.lang.Shared +import spock.lang.Specification + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.* +import static hive.pandora.constant.HiveInternalHeaders.AUTHENTICATED_USER_ID + +class PlayerControllerUnitTest extends Specification { + + def urlBase = 'http://localhost:9600/' + @Shared Player player + MockMvc mockMvc + PlayerRepository playerRepository = Mock() + + def validProfileDataJson = ''' +{ + "loginAlias": "custom2", + "email": "email", + "telnumber": "11985055502", + "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": "on", + "notify_hiveshare": "on", + "notify_hivecentral": "on", + "notify_disciplines": "on" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } +} + ''' + def setup(){ + createAnPlayer() + mockMvc = MockMvcBuilders.standaloneSetup(new PlayerController(playerRepository)).build() + } + + def createAnPlayer(){ + def options = new PlayerOptions( + "gold", + "Coffee Titan", + "on", + "on", + "on", + "on") + player = new Player( + "CompletePlayer", + "alias", + "email", + "11985054202", + "Some flavor text", + "21/04/1998", + options, + null) + } + + def "Should return BAD REQUEST when POST a Json with playerId"(){ + + given:"a JSON containing playerId" + def invalidProfileDataJson='{"playerId":10}' + + when:"perform POST" + def response=mockMvc.perform(post("$urlBase") + .header(AUTHENTICATED_USER_ID,1) + .contentType('application/json') + .content(invalidProfileDataJson)) + .andReturn() + .getResponse() + + then:"HttpResponse as BAD REQUEST" + response.getStatus()==400 + response.getErrorMessage()=="The autogenerated playerId should not be in JSON" + + } + + def "Should GET profile data successfully"(){ + + given:"Correct header key" + def headerKey=AUTHENTICATED_USER_ID + + when:"perform GET" + def response=mockMvc.perform(get("$urlBase") + .header(headerKey,val)) + .andReturn() + .getResponse() + + then:"HttpResponse as OK" + response.getStatus()==200 + + where:"numbers or string as header value" + val | _ + 1 | _ + "2" | _ + + } + + def "Should POST profile data successfully"(){ + + given:"Correct header key" + def headerKey=AUTHENTICATED_USER_ID + + when:"perform POST with valid json" + def response=mockMvc.perform(post("$urlBase") + .header(headerKey,val) + .contentType('application/json') + .content(validProfileDataJson)) + .andReturn().getResponse() + + then:"HttpResponse as OK" + response.getStatus()==200 + + where:"numbers or string as header value" + val | _ + 1 | _ + "2" | _ + + } + + def "Should return BAD REQUEST when GET with wrong Header"(){ + + given:"wrong header key" + def headerKey="wrong_key" + + and:"not null header value" + def headerValue=" " + + when:"perform GET" + def response=mockMvc.perform(get("$urlBase") + .header(headerKey,headerValue)) + .andReturn() + .getResponse() + + then:"HttpResponse as BAD REQUEST" + response.getStatus()==400 + } + + def "Should return BAD REQUEST when POST with wrong Header"(){ + + given:"wrong header key" + def headerKey="wrong_key" + + and:"not null header value" + def headerValue=" " + + when:"perform POST" + def response=mockMvc.perform(get("$urlBase") + .header(headerKey,headerValue)) + .andReturn() + .getResponse() + + then:"HttpResponse as BAD REQUEST" + response.getStatus()==400 + } + + def "Should give illegal argument exception when GET profile data"(){ + + when:"perform GET" + def response=mockMvc.perform(get("$urlBase") + .header(key,val)).andReturn().getResponse() + println response.status+key+val + + then: + thrown IllegalArgumentException + + where:"Header key or Header value is empty" + key | val | _ + AUTHENTICATED_USER_ID | null | _ + "" | "something"| _ + null | "something"| _ + } + + def "Should give illegal argument exception POST profile data"(){ + + when:"perform POST with an valid profile data json" + mockMvc.perform(post("$urlBase") + .header(key,val) + .contentType('application/json') + .content(validProfileDataJson)).andReturn() + + then: + thrown IllegalArgumentException + + where:"Header key or Header value is empty" + key | val | _ + AUTHENTICATED_USER_ID | null | _ + "" | "something"| _ + null | "something"| _ + + } + +} From 935723eaf2f7773c7f20524e45c2fe8362316cb7 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 20 May 2019 00:01:11 -0300 Subject: [PATCH 19/31] Refactored SPOCK framework tests --- .../hive/player/PlayerApplicationSpec.groovy | 4 + .../hive/player/entity/PlayerSpec.groovy | 32 +++++ .../repository/PlayerRepositorySpec.groovy | 135 ++++++++++++++++++ .../repository/PlayerRepositoryTest.groovy | 50 ------- src/test/resources/application.properties | 4 + src/test/resources/logback-test.xml | 6 + 6 files changed, 181 insertions(+), 50 deletions(-) create mode 100644 src/test/groovy/hive/player/PlayerApplicationSpec.groovy create mode 100644 src/test/groovy/hive/player/entity/PlayerSpec.groovy create mode 100644 src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy delete mode 100644 src/test/groovy/repository/PlayerRepositoryTest.groovy create mode 100644 src/test/resources/application.properties create mode 100644 src/test/resources/logback-test.xml diff --git a/src/test/groovy/hive/player/PlayerApplicationSpec.groovy b/src/test/groovy/hive/player/PlayerApplicationSpec.groovy new file mode 100644 index 0000000..42f3071 --- /dev/null +++ b/src/test/groovy/hive/player/PlayerApplicationSpec.groovy @@ -0,0 +1,4 @@ +package hive.player + +class PlayerApplicationSpec{ +} diff --git a/src/test/groovy/hive/player/entity/PlayerSpec.groovy b/src/test/groovy/hive/player/entity/PlayerSpec.groovy new file mode 100644 index 0000000..ddb3342 --- /dev/null +++ b/src/test/groovy/hive/player/entity/PlayerSpec.groovy @@ -0,0 +1,32 @@ +package hive.player.entity + +import hive.player.exception.BlankIdException +import spock.lang.Specification + +class PlayerSpec extends Specification{ + + def "Should not accept blank value as authenticated user id in constructor"(){ + when: + new Player(blankValues) + + then: + thrown BlankIdException + + where: + blankValues<<[""," "] + } + + def "Should not set blank value into authenticated user Id"(){ + + when: + def player = new Player() + player.setAuthenticatedUserId(blankValues) + + then: + thrown BlankIdException + + where: + blankValues<<[""," "] + } + +} diff --git a/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy b/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy new file mode 100644 index 0000000..595d267 --- /dev/null +++ b/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy @@ -0,0 +1,135 @@ +package hive.player.repository + +import hive.player.entity.Player +import hive.player.entity.PlayerOptions +import hive.player.entity.PlayerSocial + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest + +import spock.lang.Shared +import spock.lang.Specification + +@DataJpaTest +class PlayerRepositorySpec extends Specification { + + @Shared + Player player + @Shared + def existentAuthIdList = [] + @Shared + private PlayerRepository playerRepository + + def createAnCompletePlayer(){ + def social = new PlayerSocial() + def options = new PlayerOptions( + "gold", + "Coffee Titan", + "on", + "on", + "on", + "on") + player = new Player( + "CompletePlayer", + "alias", + "email", + "11985054202", + "Some flavor text", + "21/04/1998", + options, + social) + return player + } + + def createEmptyPlayers(int quantity){ + quantity.times { + playerRepository.save new Player(it.toString()) + existentAuthIdList+=it.toString() + } + } + @Autowired(required = true) + def initRepo(PlayerRepository playerRepository){ + this.playerRepository=playerRepository + } + + def setupSpec(){ + initRepo(playerRepository) + } + + def setup() { + createEmptyPlayers 1 + } + + def cleanup() { + playerRepository.deleteAll() + } + + def 'Should persist all user profile data'() { + + given: 'an player with complete data' + def playerToPersist = createAnCompletePlayer() + def authenticatedId = playerToPersist.getAuthenticatedUserId() + + when: 'create this player' + playerRepository.save playerToPersist + def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId + + then: 'all player information should have persisted' + player == persistedPlayer + } + + def 'Should return user profile data by authenticatedId'() { + + given: 'existent authenticatedId in database' + def authenticatedId = existentAuthenticatedId + + when: 'found in database' + def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId + + then: 'the player exists' + persistedPlayer != null + + where: + existentAuthenticatedId << existentAuthIdList + } + + def 'Should not return an user profile data by authenticatedId'(){ + + given: 'existent authenticatedId in database' + def authenticatedId = "-1" + + when: 'not found in database' + def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId + + then: 'the player not exists' + persistedPlayer == null + } + + + def 'Should return the autogenerated playerId by authenticatedId'() { + + given: 'existent userId in database' + def authenticatedId = existentAuthenticatedId + + when: 'found in database' + def persistedPlayer = playerRepository.findPlayerIdWithAuthenticatedUserId authenticatedId + + then: 'the player exists' + persistedPlayer != null + + where: + existentAuthenticatedId << existentAuthIdList + } + + def 'Should not return the autogenerated playerId by authenticatedId'(){ + + given: 'existent userId in database' + def authenticatedId = "-1" + + when: 'not found in database' + def persistedPlayer = playerRepository.findPlayerIdWithAuthenticatedUserId authenticatedId + + then: 'the player not exists' + persistedPlayer == null + } +} diff --git a/src/test/groovy/repository/PlayerRepositoryTest.groovy b/src/test/groovy/repository/PlayerRepositoryTest.groovy deleted file mode 100644 index b0198fc..0000000 --- a/src/test/groovy/repository/PlayerRepositoryTest.groovy +++ /dev/null @@ -1,50 +0,0 @@ -package repository - -import hive.player.entity.Player -import hive.player.entity.PlayerOptions -import hive.player.entity.PlayerSocial -import hive.player.repository.PlayerRepository -import org.junit.Before -import org.springframework.beans.factory.annotation.Autowired -import spock.lang.Shared -import spock.lang.Specification - -class PlayerRepositoryTest extends Specification{ - @Shared - Player player - - @Shared - PlayerRepository playerRepository - - def setup(){ - def social=new PlayerSocial() - def options = new PlayerOptions( - "ouro", - "titan do café", - "on", - "on", - "on", - "on") - player=new Player( - 1, - "alias", - "email", - "11985054202", - "String grande", - "21/04/1998", - "46358570855", - options, - social) - playerRepository.save(player) - } - - def 'Test User Creation'(){ - given:'dado' - def mina='Jennifer' - def persistedPlayer=playerRepository.getOne 1 - when:'quando' - def frase="O nome dela é $mina" - then:'então' - player==persistedPlayer - } -} diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties new file mode 100644 index 0000000..8ed45f6 --- /dev/null +++ b/src/test/resources/application.properties @@ -0,0 +1,4 @@ +# Properties for disabling Spring DEBUG & INFO log below Spring banner +logging.level.org.springframework=OFF +logging.level.root=OFF +spring.main.banner-mode=OFF \ No newline at end of file diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml new file mode 100644 index 0000000..d997923 --- /dev/null +++ b/src/test/resources/logback-test.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 3c47ec2f282ce4e68d3cc1951c868d0a3ab27f8d Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 20 May 2019 00:01:50 -0300 Subject: [PATCH 20/31] Added READ ME --- README.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/README.md b/README.md index 9d4bc68..00d7329 100644 --- a/README.md +++ b/README.md @@ -1 +1,56 @@ # player +--- +**The profile data API** + +*"A person in its life is as a player."* + +### First steps +(Configuring the environment): + +1. git clone https://github.com/hex-g/player.git + 1. cd player +2. git checkout [branch] +3. git submodule init +4. git submodule update +5. Run the project in your IDE +--- +### Usage +> URL: `http://localhost:9600/` + +#### ![#c5f015](https://placehold.it/15/c5f015/000000?text=+) `GET` +If an request profile data does not exist then a new one be created. +* `header` + * *key*: `authenticated-user-id` + * *value*: [string] + +#### ![#1589F0](https://placehold.it/15/1589F0/000000?text=+) `POST` +Inserts a new profile data or updates an existent. +* `header` + * *key*: `authenticated-user-id` + * *value*: [string] +* `body JSON` + * *value*: + ``` + { + "loginAlias": string, + "email": string, + "telnumber": string, + "flavorText": string, + "birthday": string, + "options": { + "laurel_wreath": string, + "honorific": string, + "darkmode": string["on"/"off"], + "notify_hiveshare": string["on"/"off"], + "notify_hivecentral": string["on"/"off"], + "notify_disciplines": string["on"/"off"] + }, + "social": { + "github": string, + "linkedIn": string, + "twitter": string + } + } + ``` + + From 3043462f1787720f3de927bb8d191794af27de4d Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 20 May 2019 00:02:34 -0300 Subject: [PATCH 21/31] Added new dependencies --- build.gradle | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 492a8c7..1454add 100644 --- a/build.gradle +++ b/build.gradle @@ -44,9 +44,11 @@ dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.1' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testCompile( 'org.hamcrest:hamcrest-core:1.3',//if not using delete this - 'org.spockframework:spock-core:1.3-groovy-2.5' + 'org.spockframework:spock-core:1.3-groovy-2.5', + 'org.spockframework:spock-spring:1.3-groovy-2.5' ) } From 83f7846b17224192cad69477fc100d896e15d4ec Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 20 May 2019 00:04:35 -0300 Subject: [PATCH 22/31] Removed typo --- .../java/hive/player/repository/PlayerRepository.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/hive/player/repository/PlayerRepository.java b/src/main/java/hive/player/repository/PlayerRepository.java index ad29a8e..bb88870 100644 --- a/src/main/java/hive/player/repository/PlayerRepository.java +++ b/src/main/java/hive/player/repository/PlayerRepository.java @@ -8,10 +8,10 @@ @Repository public interface PlayerRepository extends JpaRepository { - @Query("from Player where autenticateUserId= ?1") - Player getByAutenticateUserId(String autenticateUserId); + @Query("from Player where authenticatedUserId= ?1") + Player findByAuthenticatedUserId(String authenticatedUserId); - @Query("select playerId from Player where autenticateUserId= ?1") - Integer getPlayerIdWithAutenticateUserId(String autenticateUserId); + @Query("select playerId from Player where authenticatedUserId= ?1") + Integer findPlayerIdWithAuthenticatedUserId(String authenticatedUserId); } From b1dc97f4ec8a8827778a37d85dc2dc524ef6a4f2 Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 27 May 2019 00:20:06 -0300 Subject: [PATCH 23/31] added final keyword to params --- src/main/java/hive/player/entity/Player.java | 10 +++++----- .../java/hive/player/repository/PlayerRepository.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/hive/player/entity/Player.java b/src/main/java/hive/player/entity/Player.java index 9f282ef..cad3a3a 100644 --- a/src/main/java/hive/player/entity/Player.java +++ b/src/main/java/hive/player/entity/Player.java @@ -43,14 +43,11 @@ public class Player { @Column(name = "social") private PlayerSocial social; - private Player() { - } - public Integer getPlayerId() { return playerId; } - public void setPlayerId(Integer playerId) { + public void setPlayerId(final Integer playerId) { this.playerId = playerId; } @@ -58,13 +55,16 @@ public String getAuthenticatedUserId() { return authenticatedUserId; } - public void setAuthenticatedUserId(@NotNull String authenticatedUserId) { + public void setAuthenticatedUserId(@NotNull final String authenticatedUserId) { if(authenticatedUserId.isBlank()){ throw new BlankIdException(); } this.authenticatedUserId = authenticatedUserId; } + private Player() { + } + public Player( @NotNull final String authenticatedUserId, final String loginAlias, diff --git a/src/main/java/hive/player/repository/PlayerRepository.java b/src/main/java/hive/player/repository/PlayerRepository.java index bb88870..2ecee85 100644 --- a/src/main/java/hive/player/repository/PlayerRepository.java +++ b/src/main/java/hive/player/repository/PlayerRepository.java @@ -9,9 +9,9 @@ public interface PlayerRepository extends JpaRepository { @Query("from Player where authenticatedUserId= ?1") - Player findByAuthenticatedUserId(String authenticatedUserId); + Player findByAuthenticatedUserId(final String authenticatedUserId); @Query("select playerId from Player where authenticatedUserId= ?1") - Integer findPlayerIdWithAuthenticatedUserId(String authenticatedUserId); + Integer findPlayerIdWithAuthenticatedUserId(final String authenticatedUserId); } From 1643c51a8a716459cff0a9da9febb3cc932b43dc Mon Sep 17 00:00:00 2001 From: germano Date: Mon, 27 May 2019 00:20:29 -0300 Subject: [PATCH 24/31] EOL at EOF --- src/test/resources/application.properties | 2 +- src/test/resources/logback-test.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 8ed45f6..0de31d7 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -1,4 +1,4 @@ # Properties for disabling Spring DEBUG & INFO log below Spring banner logging.level.org.springframework=OFF logging.level.root=OFF -spring.main.banner-mode=OFF \ No newline at end of file +spring.main.banner-mode=OFF diff --git a/src/test/resources/logback-test.xml b/src/test/resources/logback-test.xml index d997923..4b588a4 100644 --- a/src/test/resources/logback-test.xml +++ b/src/test/resources/logback-test.xml @@ -3,4 +3,4 @@ - \ No newline at end of file + From 1d9f425eb7b9eae5dd50418b60ef63337b54e26f Mon Sep 17 00:00:00 2001 From: germano Date: Sat, 1 Jun 2019 17:03:04 -0300 Subject: [PATCH 25/31] EOL at EOF --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cdf293e..72c5d08 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,4 +13,4 @@ spring.jpa.hibernate.ddl-auto=create-drop #spring.jpa.hibernate.ddl-auto=create spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true -logging.level.org.hibernate.type=trace \ No newline at end of file +logging.level.org.hibernate.type=trace From f7a8c2f9bcd47de6927e80b09e3d7c917d04a2d8 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 2 Jun 2019 01:21:33 -0300 Subject: [PATCH 26/31] Significant change: Profile options that have two states are now boolean type --- .../java/hive/player/entity/PlayerOptions.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/hive/player/entity/PlayerOptions.java b/src/main/java/hive/player/entity/PlayerOptions.java index ec2b4b2..2a68f29 100644 --- a/src/main/java/hive/player/entity/PlayerOptions.java +++ b/src/main/java/hive/player/entity/PlayerOptions.java @@ -6,18 +6,18 @@ public class PlayerOptions { public String laurel_wreath; public String honorific; - public String darkmode; - public String notify_hiveshare; - public String notify_hivecentral; - public String notify_disciplines; + public Boolean darkmode; + public Boolean notify_hiveshare; + public Boolean notify_hivecentral; + public Boolean notify_disciplines; public PlayerOptions( final String laurel_wreath, final String honorific, - final String darkmode, - final String notify_hiveshare, - final String notify_hivecentral, - final String notify_disciplines + final Boolean darkmode, + final Boolean notify_hiveshare, + final Boolean notify_hivecentral, + final Boolean notify_disciplines ) { this.laurel_wreath = laurel_wreath; this.honorific = honorific; From 530cadfdefe6e80e967199d49cda1fcb73681faf Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 2 Jun 2019 01:22:08 -0300 Subject: [PATCH 27/31] Deleted: BlankIdException --- src/main/java/hive/player/entity/Player.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/hive/player/entity/Player.java b/src/main/java/hive/player/entity/Player.java index cad3a3a..642af4e 100644 --- a/src/main/java/hive/player/entity/Player.java +++ b/src/main/java/hive/player/entity/Player.java @@ -2,7 +2,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import hive.player.exception.BlankIdException; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -11,7 +10,7 @@ @Table(name = "tb_user_profile") public class Player { @Id - @JsonIgnore + @JsonProperty @GeneratedValue(strategy = GenerationType.IDENTITY) //is some DBMS like Oracle you should change the strategy private Integer playerId; @@ -56,9 +55,6 @@ public String getAuthenticatedUserId() { } public void setAuthenticatedUserId(@NotNull final String authenticatedUserId) { - if(authenticatedUserId.isBlank()){ - throw new BlankIdException(); - } this.authenticatedUserId = authenticatedUserId; } From 1df46f3d4d76e84bce928aff61b978d4ece12017 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 2 Jun 2019 01:22:29 -0300 Subject: [PATCH 28/31] Deleted: findPlayerIdWithAuthenticatedUserId --- src/main/java/hive/player/repository/PlayerRepository.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/hive/player/repository/PlayerRepository.java b/src/main/java/hive/player/repository/PlayerRepository.java index 2ecee85..b17568a 100644 --- a/src/main/java/hive/player/repository/PlayerRepository.java +++ b/src/main/java/hive/player/repository/PlayerRepository.java @@ -8,10 +8,6 @@ @Repository public interface PlayerRepository extends JpaRepository { - @Query("from Player where authenticatedUserId= ?1") Player findByAuthenticatedUserId(final String authenticatedUserId); - @Query("select playerId from Player where authenticatedUserId= ?1") - Integer findPlayerIdWithAuthenticatedUserId(final String authenticatedUserId); - } From 0e656c22689228d79be5367463f3cb60daa0bda8 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 2 Jun 2019 01:23:13 -0300 Subject: [PATCH 29/31] Deleted: findPlayerIdWithAuthenticatedUserId --- .../hive/player/controller/PlayerController.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/hive/player/controller/PlayerController.java b/src/main/java/hive/player/controller/PlayerController.java index ec6c5a7..240d5c4 100644 --- a/src/main/java/hive/player/controller/PlayerController.java +++ b/src/main/java/hive/player/controller/PlayerController.java @@ -30,7 +30,7 @@ public void insertProfileData( @RequestHeader(name = AUTHENTICATED_USER_ID) final String authenticatedUserId, @RequestBody final Player player ) { - if(player.getPlayerId()!=null){ + if(player.getPlayerId() != null){ throw new PlayerIdShouldNotBeInJsonException(); } updatePlayerCorrelatedWithTheAuthenticatedId(player, authenticatedUserId); @@ -51,10 +51,12 @@ private void updatePlayerCorrelatedWithTheAuthenticatedId( final Player player, final String authenticatedUserId ) { - final var autogeneratedPlayerId = - playerRepository.findPlayerIdWithAuthenticatedUserId(authenticatedUserId); - if (autogeneratedPlayerId != null) { - player.setPlayerId(autogeneratedPlayerId); + final var playerFound=playerRepository.findByAuthenticatedUserId(authenticatedUserId); + if(playerFound != null) { + final var autogeneratedPlayerId = playerFound.getPlayerId(); + if (autogeneratedPlayerId != null) { + player.setPlayerId(autogeneratedPlayerId); + } } } } From 54360d103ee987dbc10a663aee6c8279cd30986f Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 2 Jun 2019 01:26:17 -0300 Subject: [PATCH 30/31] Refactored test names --- .../PlayerControllerIntegrationTest.groovy | 88 +++---- .../PlayerControllerUnitTest.groovy | 224 +++++++++--------- .../repository/PlayerRepositorySpec.groovy | 76 +++--- 3 files changed, 201 insertions(+), 187 deletions(-) diff --git a/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy b/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy index 7e9b4c4..a674a93 100644 --- a/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy +++ b/src/test/groovy/hive/player/controller/PlayerControllerIntegrationTest.groovy @@ -10,7 +10,6 @@ import groovyx.net.http.RESTClient import static hive.pandora.constant.HiveInternalHeaders.* -/*Integration test. only work with the system up*/ class PlayerControllerIntegrationTest extends Specification { @Shared @@ -25,96 +24,99 @@ class PlayerControllerIntegrationTest extends Specification { def urlBase = 'http://localhost:9600/' - def validProfileDataJson = ''' -{ - "loginAlias": "Integration_Test", - "email": "integration@test.com", - "telnumber": "11987654321", - "flavorText": "Large string Lorem Ipsum dolor aquicumsitum amet", - "birthday": "21/04/1998", - "options": { - "laurel_wreath": "CHALLENGER", - "honorific": "Coffee Titan", - "darkmode": "on", - "notify_hiveshare": "on", - "notify_hivecentral": "on", - "notify_disciplines": "on" - }, - "social": { - "github": "git", - "linkedIn": "linkedin", - "twitter": "@twitter" - } -} - ''' + def validProfileDataJson = $/ + { + "loginAlias": "Integration_Test", + "email": "integration@test.com", + "telnumber": "11987654321", + "flavorText": "Large string Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "options": { + "laurel_wreath": "CHALLENGER", + "honorific": "Coffee Titan", + "darkmode": "true", + "notify_hiveshare": "true", + "notify_hivecentral": "true", + "notify_disciplines": "true" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } + } + /$ def cleanupSpec(){ //should have some delete method in the original application } - def 'Should GET user successfully'() { + def 'Perform GET with correct header and expect HttpStatus OK'() { - given: 'perform GET with correct header' + given: def response = client.get( headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"]) - expect: 'HttpStatus OK' + expect: response.status == 200 } - def 'Should POST an user successfully'() { + def 'Perform POST with valid Json and expect HttpStatus OK'() { - given: 'perform POST with valid Json' + given: def response = client.post( headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"], body: "$validProfileDataJson") - expect: 'HttpStatus OK' + expect: response.status == 200 } - def 'Should return BAD REQUEST when GET with wrong Header key'() { + def 'Perform GET with wrong Header key and expect HttpStatus BAD REQUEST'() { - given: 'perform GET with wrong Header key' + given: def response = client.get( headers: ['wrong_key': "${integrationTestHeaderValue}"]) - expect: 'HttpStatus BAD REQUEST' + expect: response.status == 400 } - def 'Should return BAD REQUEST when POST with wrong Header key'() { + def 'Perform POST with wrong Header key and expect HttpStatus BAD REQUEST'() { - given: 'perform POST with wrong Header key' + given: def response = client.post( headers: ["wrong_key": '1']) - expect: 'HttpStatus BAD REQUEST' + expect: response.status == 400 } - def 'Should return BAD REQUEST when POST with an empty body request'() { + def 'Perform POST with empty body request and expect HttpStatus BAD REQUEST'() { - given: 'perform POST with empty body request' + given: def response = client.post( headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"]) - expect: 'HttpStatus BAD REQUEST' + expect: response.status == 400 } - def 'Should return BAD REQUEST when POST a body request with PlayerId'() { + def ''' + Given Json containing playerId, + when user profile data is inserted, + then HttpStatus BAD REQUEST + '''() { - given: 'Json containing playerId as Header key' + given: def invalidProfileDataJson='{"playerId": 10}' - when: 'When user profile data is inserted' + when: def response = client.post( headers: ["$AUTHENTICATED_USER_ID": "${integrationTestHeaderValue}"], body: ["$invalidProfileDataJson"]) - - then: 'HttpStatus ok request is received' + then: response.status == 400 } diff --git a/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy b/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy index 37e2990..92aebc2 100644 --- a/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy +++ b/src/test/groovy/hive/player/controller/PlayerControllerUnitTest.groovy @@ -4,7 +4,6 @@ package hive.player.controller import hive.player.entity.Player import hive.player.entity.PlayerOptions import hive.player.repository.PlayerRepository -import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.web.servlet.MockMvc import org.springframework.test.web.servlet.setup.MockMvcBuilders import spock.lang.Shared @@ -21,26 +20,26 @@ class PlayerControllerUnitTest extends Specification { PlayerRepository playerRepository = Mock() def validProfileDataJson = ''' -{ - "loginAlias": "custom2", - "email": "email", - "telnumber": "11985055502", - "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", - "birthday": "21/04/1998", - "options": { - "laurel_wreath": "ouro", - "honorific": "titan do café", - "darkmode": "on", - "notify_hiveshare": "on", - "notify_hivecentral": "on", - "notify_disciplines": "on" - }, - "social": { - "github": "git", - "linkedIn": "linkedin", - "twitter": "@twitter" + { + "loginAlias": "custom2", + "email": "email", + "telnumber": "11985055502", + "flavorText": "String grande Lorem Ipsum dolor aquicumsitum amet", + "birthday": "21/04/1998", + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": "true", + "notify_hiveshare": "true", + "notify_hivecentral": "true", + "notify_disciplines": "true" + }, + "social": { + "github": "git", + "linkedIn": "linkedin", + "twitter": "@twitter" + } } -} ''' def setup(){ createAnPlayer() @@ -51,10 +50,10 @@ class PlayerControllerUnitTest extends Specification { def options = new PlayerOptions( "gold", "Coffee Titan", - "on", - "on", - "on", - "on") + true, + true, + true, + true) player = new Player( "CompletePlayer", "alias", @@ -72,7 +71,8 @@ class PlayerControllerUnitTest extends Specification { def invalidProfileDataJson='{"playerId":10}' when:"perform POST" - def response=mockMvc.perform(post("$urlBase") + def response = + mockMvc.perform(post("$urlBase") .header(AUTHENTICATED_USER_ID,1) .contentType('application/json') .content(invalidProfileDataJson)) @@ -85,119 +85,127 @@ class PlayerControllerUnitTest extends Specification { } - def "Should GET profile data successfully"(){ + def ''' + Given profile options with valid values in boolean fields, + when perform POST, + then HttpResponse as BAD REQUEST. + '''(){ + + given: + def validProfileOptionsJson= $/ + { + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": $validBooleanValues, + "notify_hiveshare": $validBooleanValues, + "notify_hivecentral": $validBooleanValues, + "notify_disciplines": $validBooleanValues + } + } + /$ + + when: + def response = + mockMvc.perform(post("$urlBase") + .header(AUTHENTICATED_USER_ID,1) + .contentType('application/json') + .content(validProfileOptionsJson)) + .andReturn() + .getResponse() + + then: + response.getStatus()==200 + + where: + validBooleanValues << ['\"True\"', '\"true\"', true, 1, '\"False\"', '\"false\"', false, 0] + } + + def ''' + Given profile options with string values in boolean fields, + when perform POST, + then HttpResponse as BAD REQUEST. + '''(){ + + given: + def invalidProfileOptionsJson= $/ + { + "options": { + "laurel_wreath": "ouro", + "honorific": "titan do café", + "darkmode": $testedStringValues, + "notify_hiveshare": $testedStringValues, + "notify_hivecentral": $testedStringValues, + "notify_disciplines": $testedStringValues + } + } + /$ + + when: + def response = + mockMvc.perform(post("$urlBase") + .header(AUTHENTICATED_USER_ID,1) + .contentType('application/json') + .content(invalidProfileOptionsJson)) + .andReturn() + .getResponse() + then: + response.getStatus() == 400 + + where: + testedStringValues << ['\"TrUe\"', '\"FALSE\"', '\"Something\"'] + } - given:"Correct header key" + def ''' + Given correct header key, + when perform GET, + then HttpResponse as OK. + Where header value accepts numbers or string to query. + '''(){ + + given: def headerKey=AUTHENTICATED_USER_ID - when:"perform GET" + when: def response=mockMvc.perform(get("$urlBase") .header(headerKey,val)) .andReturn() .getResponse() - then:"HttpResponse as OK" + then: response.getStatus()==200 - where:"numbers or string as header value" + where: val | _ 1 | _ "2" | _ } - def "Should POST profile data successfully"(){ + def ''' + Given correct header key, + when perform POST with valid json, + then HttpResponse as OK. + Where header value accepts numbers or string to query. + '''(){ - given:"Correct header key" + given: def headerKey=AUTHENTICATED_USER_ID - when:"perform POST with valid json" + when: def response=mockMvc.perform(post("$urlBase") .header(headerKey,val) .contentType('application/json') .content(validProfileDataJson)) .andReturn().getResponse() - then:"HttpResponse as OK" + then: response.getStatus()==200 - where:"numbers or string as header value" + where: val | _ 1 | _ "2" | _ } - - def "Should return BAD REQUEST when GET with wrong Header"(){ - - given:"wrong header key" - def headerKey="wrong_key" - - and:"not null header value" - def headerValue=" " - - when:"perform GET" - def response=mockMvc.perform(get("$urlBase") - .header(headerKey,headerValue)) - .andReturn() - .getResponse() - - then:"HttpResponse as BAD REQUEST" - response.getStatus()==400 - } - - def "Should return BAD REQUEST when POST with wrong Header"(){ - - given:"wrong header key" - def headerKey="wrong_key" - - and:"not null header value" - def headerValue=" " - - when:"perform POST" - def response=mockMvc.perform(get("$urlBase") - .header(headerKey,headerValue)) - .andReturn() - .getResponse() - - then:"HttpResponse as BAD REQUEST" - response.getStatus()==400 - } - - def "Should give illegal argument exception when GET profile data"(){ - - when:"perform GET" - def response=mockMvc.perform(get("$urlBase") - .header(key,val)).andReturn().getResponse() - println response.status+key+val - - then: - thrown IllegalArgumentException - - where:"Header key or Header value is empty" - key | val | _ - AUTHENTICATED_USER_ID | null | _ - "" | "something"| _ - null | "something"| _ - } - - def "Should give illegal argument exception POST profile data"(){ - - when:"perform POST with an valid profile data json" - mockMvc.perform(post("$urlBase") - .header(key,val) - .contentType('application/json') - .content(validProfileDataJson)).andReturn() - - then: - thrown IllegalArgumentException - - where:"Header key or Header value is empty" - key | val | _ - AUTHENTICATED_USER_ID | null | _ - "" | "something"| _ - null | "something"| _ - - } - } diff --git a/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy b/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy index 595d267..d73a80f 100644 --- a/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy +++ b/src/test/groovy/hive/player/repository/PlayerRepositorySpec.groovy @@ -20,15 +20,15 @@ class PlayerRepositorySpec extends Specification { @Shared private PlayerRepository playerRepository - def createAnCompletePlayer(){ + def createACompletePlayer(){ def social = new PlayerSocial() def options = new PlayerOptions( "gold", "Coffee Titan", - "on", - "on", - "on", - "on") + true, + true, + true, + true) player = new Player( "CompletePlayer", "alias", @@ -64,72 +64,76 @@ class PlayerRepositorySpec extends Specification { playerRepository.deleteAll() } - def 'Should persist all user profile data'() { + def ''' + Given an player with complete data, + when create this player, + then all player information should have persisted. + '''() { - given: 'an player with complete data' - def playerToPersist = createAnCompletePlayer() + given: + def playerToPersist = createACompletePlayer() def authenticatedId = playerToPersist.getAuthenticatedUserId() - when: 'create this player' + when: playerRepository.save playerToPersist def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId - then: 'all player information should have persisted' + then: player == persistedPlayer } - def 'Should return user profile data by authenticatedId'() { + def ''' + Given existent authenticatedUserId, + when search in database, + then the player exists. + '''() { - given: 'existent authenticatedId in database' + given: def authenticatedId = existentAuthenticatedId - when: 'found in database' + when: def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId - then: 'the player exists' + then: persistedPlayer != null where: existentAuthenticatedId << existentAuthIdList } - def 'Should not return an user profile data by authenticatedId'(){ + def ''' + Given not existent authenticatedUserId, + when search in database, + then the player not exists. + '''() { - given: 'existent authenticatedId in database' + given: def authenticatedId = "-1" - when: 'not found in database' + when: def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId - then: 'the player not exists' + then: persistedPlayer == null } - def 'Should return the autogenerated playerId by authenticatedId'() { + def ''' + Given existent authenticatedUserId, + when search in database, + then the found player have a not null playerId. + '''() { - given: 'existent userId in database' + given: def authenticatedId = existentAuthenticatedId - when: 'found in database' - def persistedPlayer = playerRepository.findPlayerIdWithAuthenticatedUserId authenticatedId + when: + def persistedPlayer = playerRepository.findByAuthenticatedUserId authenticatedId - then: 'the player exists' - persistedPlayer != null + then: + persistedPlayer.getPlayerId() != null where: existentAuthenticatedId << existentAuthIdList } - - def 'Should not return the autogenerated playerId by authenticatedId'(){ - - given: 'existent userId in database' - def authenticatedId = "-1" - - when: 'not found in database' - def persistedPlayer = playerRepository.findPlayerIdWithAuthenticatedUserId authenticatedId - - then: 'the player not exists' - persistedPlayer == null - } } From 7ca616b996b767cadb854dbfb6b7871047d09bc6 Mon Sep 17 00:00:00 2001 From: germano Date: Sun, 29 Sep 2019 14:31:35 -0300 Subject: [PATCH 31/31] Added spring fox swagger :smile: --- build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1454add..80dc266 100644 --- a/build.gradle +++ b/build.gradle @@ -37,14 +37,20 @@ dependencies { implementation 'javax.xml.bind:jaxb-api:2.3.1' implementation 'javax.activation:activation:1.1.1' implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.2' + //production db: + //implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.16' + //development db: + implementation 'com.h2database:h2' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'com.h2database:h2' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.codehaus.groovy.modules.http-builder:http-builder:0.7.1' testImplementation 'org.springframework.boot:spring-boot-starter-test' + compile 'io.springfox:springfox-swagger2:2.9.2' + compile 'io.springfox:springfox-swagger-ui:2.9.2' + testCompile( 'org.hamcrest:hamcrest-core:1.3',//if not using delete this 'org.spockframework:spock-core:1.3-groovy-2.5', @@ -58,3 +64,6 @@ dependencyManagement { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } +bootJar(){ + launchScript() +}