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