From 9a3cbc440c3f8f9e9ed8b5772e330daae4310df3 Mon Sep 17 00:00:00 2001 From: Felipe D'Abrantes <felidabrantes@gmail> Date: Sun, 12 Mar 2023 17:00:04 +0000 Subject: [PATCH] Create Scala Play project (#17) --- .../$model__Camel$Controller.scala | 46 ++++++++++++ .../app/views/$model__camel$/form.scala.html | 12 +++ .../feed-service/.g8/form/default.properties | 2 + .../$model__Camel$ControllerSpec.scala | 71 ++++++++++++++++++ backend-services/feed-service/.gitignore | 9 +++ .../app/controllers/HomeController.scala | 24 ++++++ .../feed-service/app/views/index.scala.html | 5 ++ .../feed-service/app/views/main.scala.html | 25 ++++++ backend-services/feed-service/build.sbt | 17 +++++ backend-services/feed-service/build.sc | 11 +++ .../feed-service/conf/application.conf | 1 + .../feed-service/conf/logback.xml | 40 ++++++++++ backend-services/feed-service/conf/messages | 1 + backend-services/feed-service/conf/routes | 10 +++ .../feed-service/project/build.properties | 1 + .../feed-service/project/plugins.sbt | 2 + .../feed-service/public/images/favicon.png | Bin 0 -> 687 bytes .../feed-service/public/javascripts/main.js | 0 .../feed-service/public/stylesheets/main.css | 0 .../test/controllers/HomeControllerSpec.scala | 45 +++++++++++ 20 files changed, 322 insertions(+) create mode 100644 backend-services/feed-service/.g8/form/app/controllers/$model__Camel$Controller.scala create mode 100644 backend-services/feed-service/.g8/form/app/views/$model__camel$/form.scala.html create mode 100644 backend-services/feed-service/.g8/form/default.properties create mode 100644 backend-services/feed-service/.g8/form/test/controllers/$model__Camel$ControllerSpec.scala create mode 100644 backend-services/feed-service/.gitignore create mode 100644 backend-services/feed-service/app/controllers/HomeController.scala create mode 100644 backend-services/feed-service/app/views/index.scala.html create mode 100644 backend-services/feed-service/app/views/main.scala.html create mode 100644 backend-services/feed-service/build.sbt create mode 100644 backend-services/feed-service/build.sc create mode 100644 backend-services/feed-service/conf/application.conf create mode 100644 backend-services/feed-service/conf/logback.xml create mode 100644 backend-services/feed-service/conf/messages create mode 100644 backend-services/feed-service/conf/routes create mode 100644 backend-services/feed-service/project/build.properties create mode 100644 backend-services/feed-service/project/plugins.sbt create mode 100644 backend-services/feed-service/public/images/favicon.png create mode 100644 backend-services/feed-service/public/javascripts/main.js create mode 100644 backend-services/feed-service/public/stylesheets/main.css create mode 100644 backend-services/feed-service/test/controllers/HomeControllerSpec.scala diff --git a/backend-services/feed-service/.g8/form/app/controllers/$model__Camel$Controller.scala b/backend-services/feed-service/.g8/form/app/controllers/$model__Camel$Controller.scala new file mode 100644 index 00000000..6977727b --- /dev/null +++ b/backend-services/feed-service/.g8/form/app/controllers/$model__Camel$Controller.scala @@ -0,0 +1,46 @@ +package controllers + +import javax.inject._ +import play.api.mvc._ + +import play.api.data._ +import play.api.data.Forms._ + +case class $model;format="Camel"$Data(name: String, age: Int) + +// NOTE: Add the following to conf/routes to enable compilation of this class: +/* +GET /$model;format="camel"$ controllers.$model;format="Camel"$Controller.$model;format="camel"$Get() +POST /$model;format="camel"$ controllers.$model;format="Camel"$Controller.$model;format="camel"$Post() +*/ + +/** + * $model;format="Camel"$ form controller for Play Scala + */ +class $model;format="Camel"$Controller @Inject()(mcc: MessagesControllerComponents) extends MessagesAbstractController(mcc) { + + val $model;format="camel"$Form = Form( + mapping( + "name" -> text, + "age" -> number + )($model;format="Camel"$Data.apply)($model;format="Camel"$Data.unapply) + ) + + def $model;format="camel"$Get() = Action { implicit request: MessagesRequest[AnyContent] => + Ok(views.html.$model;format="camel"$.form($model;format="camel"$Form)) + } + + def $model;format="camel"$Post() = Action { implicit request: MessagesRequest[AnyContent] => + $model;format="camel"$Form.bindFromRequest().fold( + formWithErrors => { + // binding failure, you retrieve the form containing errors: + BadRequest(views.html.$model;format="camel"$.form(formWithErrors)) + }, + $model;format="camel"$Data => { + /* binding success, you get the actual value. */ + /* flashing uses a short lived cookie */ + Redirect(routes.$model;format="Camel"$Controller.$model;format="camel"$Get()).flashing("success" -> ("Successful " + $model;format="camel"$Data.toString)) + } + ) + } +} diff --git a/backend-services/feed-service/.g8/form/app/views/$model__camel$/form.scala.html b/backend-services/feed-service/.g8/form/app/views/$model__camel$/form.scala.html new file mode 100644 index 00000000..14674ba6 --- /dev/null +++ b/backend-services/feed-service/.g8/form/app/views/$model__camel$/form.scala.html @@ -0,0 +1,12 @@ +@($model;format="camel"$Form: Form[$model;format="Camel"$Data])(implicit request: MessagesRequestHeader) + +<h1>$model;format="camel"$ form</h1> + +@request.flash.get("success").getOrElse("") + +@helper.form(action = routes.$model;format="Camel"$Controller.$model;format="camel"$Post()) { + @helper.CSRF.formField + @helper.inputText($model;format="camel"$Form("name")) + @helper.inputText($model;format="camel"$Form("age")) + <input type="submit" value="submit"/> +} diff --git a/backend-services/feed-service/.g8/form/default.properties b/backend-services/feed-service/.g8/form/default.properties new file mode 100644 index 00000000..32090f30 --- /dev/null +++ b/backend-services/feed-service/.g8/form/default.properties @@ -0,0 +1,2 @@ +description = Generates a Controller with form handling +model = user diff --git a/backend-services/feed-service/.g8/form/test/controllers/$model__Camel$ControllerSpec.scala b/backend-services/feed-service/.g8/form/test/controllers/$model__Camel$ControllerSpec.scala new file mode 100644 index 00000000..d2517431 --- /dev/null +++ b/backend-services/feed-service/.g8/form/test/controllers/$model__Camel$ControllerSpec.scala @@ -0,0 +1,71 @@ +package controllers + +import play.api.mvc._ +import play.api.i18n._ +import org.scalatestplus.play._ +import org.scalatestplus.play.guice.GuiceOneAppPerTest +import play.api.http.FileMimeTypes +import play.api.test._ +import play.api.test.Helpers._ +import play.api.test.CSRFTokenHelper._ + +import scala.concurrent.ExecutionContext + +/** + * $model;format="Camel"$ form controller specs + */ +class $model;format="Camel"$ControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting { + + // Provide stubs for components based off Helpers.stubControllerComponents() + class StubComponents(cc:ControllerComponents = stubControllerComponents()) extends MessagesControllerComponents { + override val parsers: PlayBodyParsers = cc.parsers + override val messagesApi: MessagesApi = cc.messagesApi + override val langs: Langs = cc.langs + override val fileMimeTypes: FileMimeTypes = cc.fileMimeTypes + override val executionContext: ExecutionContext = cc.executionContext + override val actionBuilder: ActionBuilder[Request, AnyContent] = cc.actionBuilder + override val messagesActionBuilder: MessagesActionBuilder = new DefaultMessagesActionBuilderImpl(parsers.default, messagesApi)(executionContext) + } + + "$model;format="Camel"$Controller GET" should { + + "render the index page from a new instance of controller" in { + val controller = new $model;format="Camel"$Controller(new StubComponents()) + val request = FakeRequest().withCSRFToken + val home = controller.$model;format="camel"$Get().apply(request) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + } + + "render the index page from the application" in { + val controller = inject[$model;format="Camel"$Controller] + val request = FakeRequest().withCSRFToken + val home = controller.$model;format="camel"$Get().apply(request) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + } + + "render the index page from the router" in { + val request = CSRFTokenHelper.addCSRFToken(FakeRequest(GET, "/$model;format="camel"$")) + val home = route(app, request).get + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + } + } + + "$model;format="Camel"$Controller POST" should { + "process form" in { + val request = { + FakeRequest(POST, "/$model;format="camel"$") + .withFormUrlEncodedBody("name" -> "play", "age" -> "4") + } + val home = route(app, request).get + + status(home) mustBe SEE_OTHER + } + } + +} diff --git a/backend-services/feed-service/.gitignore b/backend-services/feed-service/.gitignore new file mode 100644 index 00000000..dce73038 --- /dev/null +++ b/backend-services/feed-service/.gitignore @@ -0,0 +1,9 @@ +logs +target +/.bsp +/.idea +/.idea_modules +/.classpath +/.project +/.settings +/RUNNING_PID diff --git a/backend-services/feed-service/app/controllers/HomeController.scala b/backend-services/feed-service/app/controllers/HomeController.scala new file mode 100644 index 00000000..272ed2d9 --- /dev/null +++ b/backend-services/feed-service/app/controllers/HomeController.scala @@ -0,0 +1,24 @@ +package controllers + +import javax.inject._ +import play.api._ +import play.api.mvc._ + +/** + * This controller creates an `Action` to handle HTTP requests to the + * application's home page. + */ +@Singleton +class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController { + + /** + * Create an Action to render an HTML page. + * + * The configuration in the `routes` file means that this method + * will be called when the application receives a `GET` request with + * a path of `/`. + */ + def index() = Action { implicit request: Request[AnyContent] => + Ok(views.html.index()) + } +} diff --git a/backend-services/feed-service/app/views/index.scala.html b/backend-services/feed-service/app/views/index.scala.html new file mode 100644 index 00000000..68d37fb1 --- /dev/null +++ b/backend-services/feed-service/app/views/index.scala.html @@ -0,0 +1,5 @@ +@() + +@main("Welcome to Play") { + <h1>Welcome to Play!</h1> +} diff --git a/backend-services/feed-service/app/views/main.scala.html b/backend-services/feed-service/app/views/main.scala.html new file mode 100644 index 00000000..808a8b89 --- /dev/null +++ b/backend-services/feed-service/app/views/main.scala.html @@ -0,0 +1,25 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + +<!DOCTYPE html> +<html lang="en"> + <head> + @* Here's where we render the page title `String`. *@ + <title>@title</title> + <link rel="stylesheet" media="screen" href="@routes.Assets.versioned("stylesheets/main.css")"> + <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")"> + + </head> + <body> + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + <script src="@routes.Assets.versioned("javascripts/main.js")" type="text/javascript"></script> + </body> +</html> diff --git a/backend-services/feed-service/build.sbt b/backend-services/feed-service/build.sbt new file mode 100644 index 00000000..ed852311 --- /dev/null +++ b/backend-services/feed-service/build.sbt @@ -0,0 +1,17 @@ +name := """feed-service""" +organization := "com.daily" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayScala) + +scalaVersion := "2.13.10" + +libraryDependencies += guice +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test + +// Adds additional packages into Twirl +//TwirlKeys.templateImports += "com.daily.controllers._" + +// Adds additional packages into conf/routes +// play.sbt.routes.RoutesKeys.routesImport += "com.daily.binders._" diff --git a/backend-services/feed-service/build.sc b/backend-services/feed-service/build.sc new file mode 100644 index 00000000..fe14b81a --- /dev/null +++ b/backend-services/feed-service/build.sc @@ -0,0 +1,11 @@ +import mill._ +import $ivy.`com.lihaoyi::mill-contrib-playlib:`, mill.playlib._ + +object feedservice extends PlayModule with SingleModule { + + def scalaVersion = "2.13.10" + def playVersion = "2.8.19" + def twirlVersion = "1.5.1" + + object test extends PlayTests +} diff --git a/backend-services/feed-service/conf/application.conf b/backend-services/feed-service/conf/application.conf new file mode 100644 index 00000000..cb94680e --- /dev/null +++ b/backend-services/feed-service/conf/application.conf @@ -0,0 +1 @@ +# https://www.playframework.com/documentation/latest/Configuration diff --git a/backend-services/feed-service/conf/logback.xml b/backend-services/feed-service/conf/logback.xml new file mode 100644 index 00000000..a73d2016 --- /dev/null +++ b/backend-services/feed-service/conf/logback.xml @@ -0,0 +1,40 @@ +<!-- https://www.playframework.com/documentation/latest/SettingsLogger --> +<configuration> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <file>${application.home:-.}/logs/application.log</file> + <encoder> + <charset>UTF-8</charset> + <pattern> + %d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %cyan(%logger{36}) %magenta(%X{akkaSource}) %msg%n + </pattern> + </encoder> + </appender> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <withJansi>true</withJansi> + <encoder> + <charset>UTF-8</charset> + <pattern> + %d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %cyan(%logger{36}) %magenta(%X{akkaSource}) %msg%n + </pattern> + </encoder> + </appender> + + <appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="FILE" /> + </appender> + + <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="STDOUT" /> + </appender> + + <logger name="play" level="INFO" /> + <logger name="application" level="DEBUG" /> + + <root level="WARN"> + <appender-ref ref="ASYNCFILE" /> + <appender-ref ref="ASYNCSTDOUT" /> + </root> + +</configuration> diff --git a/backend-services/feed-service/conf/messages b/backend-services/feed-service/conf/messages new file mode 100644 index 00000000..0226738a --- /dev/null +++ b/backend-services/feed-service/conf/messages @@ -0,0 +1 @@ +# https://www.playframework.com/documentation/latest/ScalaI18N diff --git a/backend-services/feed-service/conf/routes b/backend-services/feed-service/conf/routes new file mode 100644 index 00000000..60e8169b --- /dev/null +++ b/backend-services/feed-service/conf/routes @@ -0,0 +1,10 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# https://www.playframework.com/documentation/latest/ScalaRouting +# ~~~~ + +# An example controller showing a sample home page +GET / controllers.HomeController.index() + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) diff --git a/backend-services/feed-service/project/build.properties b/backend-services/feed-service/project/build.properties new file mode 100644 index 00000000..563a014d --- /dev/null +++ b/backend-services/feed-service/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.7.2 diff --git a/backend-services/feed-service/project/plugins.sbt b/backend-services/feed-service/project/plugins.sbt new file mode 100644 index 00000000..8846622e --- /dev/null +++ b/backend-services/feed-service/project/plugins.sbt @@ -0,0 +1,2 @@ +addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.19") +addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.13.1") diff --git a/backend-services/feed-service/public/images/favicon.png b/backend-services/feed-service/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d92d2ae47434d9a61c90bc205e099b673b9dd5 GIT binary patch literal 687 zcmV;g0#N;lP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!QAtEWRCwByQ_D^iK@>ezT{T_ZJ?}AL z5NC{NW(ESID=>(O3&Eg<jc#1IXXDbpa3kzAqCa4CuL%noS4M*p6G$XTBxH;c1(`>8 zmA9J&6c`h4_f6L;=bU>_H8aNG`kfvCj9zomNt)?O;rzWqZs0LEt%1WB218%1fo9uB zsW^yhBR7C(mqN%GEK9&ms<Bh&a@9?DVRorrn`tz5Jc|kZD<S~SZAt~(QDtE(q>g0~ zWY?#bf4q8G-~2KttQZ($odJvy&_-~f?9*ThK@fwR$U^1)p*8=_+^3BXx0$i1BC8XC zr21u6D5nVK&^!dOAw&|1E;qC3uFNj3*Jj#&%Oje@0D-nhfmM*o%^5f}-pxQ07(95H z3|LoV>V19w#rLgmRmtVy9!T3M3FUE3><0T8&b3yEsWcLW`0(=1+qsqc(k(ymBLK0h zK!6(6$7MX~M`-QA2$wk7n(7hhkJ}4Rwi-Vd(_ZFX1Yk7TXuB0IJYpo@kLb2G8m)E{ z`9v=!hi}fOytKckfN^C@6+Z*+MVI9-W_p@_3yyR#UYc0FTpD}i#k>c!wYCS)4v@E$ zchZCo=zV@)`v^$;V18ixdjFMY#q^2$wEX%{f(XD8POnsn$bpbClpC@hPxjzy<x*{^ zcy^kOJ*C_^SXu<YrK(tVoM~gDL3M_5C(5I%<K+>O>pY|*pF3UU2tYcCN?<AaQ8=pI zeOr_LqtA<(u0wJ=0`QoV>rUk{Sskej70Mmu9vPwMYhO1m{AxAt(zqDT|0jP7FaX=6 V`?~}E4H^Id002ovPDHLkV1hC)G==~G literal 0 HcmV?d00001 diff --git a/backend-services/feed-service/public/javascripts/main.js b/backend-services/feed-service/public/javascripts/main.js new file mode 100644 index 00000000..e69de29b diff --git a/backend-services/feed-service/public/stylesheets/main.css b/backend-services/feed-service/public/stylesheets/main.css new file mode 100644 index 00000000..e69de29b diff --git a/backend-services/feed-service/test/controllers/HomeControllerSpec.scala b/backend-services/feed-service/test/controllers/HomeControllerSpec.scala new file mode 100644 index 00000000..97947556 --- /dev/null +++ b/backend-services/feed-service/test/controllers/HomeControllerSpec.scala @@ -0,0 +1,45 @@ +package controllers + +import org.scalatestplus.play._ +import org.scalatestplus.play.guice._ +import play.api.test._ +import play.api.test.Helpers._ + +/** + * Add your spec here. + * You can mock out a whole application including requests, plugins etc. + * + * For more information, see https://www.playframework.com/documentation/latest/ScalaTestingWithScalaTest + */ +class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting { + + "HomeController GET" should { + + "render the index page from a new instance of controller" in { + val controller = new HomeController(stubControllerComponents()) + val home = controller.index().apply(FakeRequest(GET, "/")) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the application" in { + val controller = inject[HomeController] + val home = controller.index().apply(FakeRequest(GET, "/")) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the router" in { + val request = FakeRequest(GET, "/") + val home = route(app, request).get + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + } +} -- GitLab