Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump body-parser and express in /election-ui-javascript #4

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion election-api-scala/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The API has 3 endpoints:

During your assessment we will ask you to work though the task in `tasks.md` with a pair. Please do not work on or complete these prior to the assessment.

:warning: If you make any changes to the code, please ensure you return it to it's initial (HEAD) state before your assessment.
__Warning:__ If you make any changes to the code, please ensure you return it to it's initial (HEAD) state before your assessment.

## Prerequisites
- Java 11
Expand All @@ -36,6 +36,10 @@ During your assessment we will ask you to work though the task in `tasks.md` wit

`sbt run`

You may get a port error when you try to run this. If so, run the following command:

`export PLAY_HTTP_PORT=9001`

### To Test

`sbt test`
3 changes: 1 addition & 2 deletions election-api-scala/app/controllers/ResultsController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ class ResultsController @Inject()(val controllerComponents: ControllerComponents
}

def getScoreboard: Action[AnyContent] = Action {

Ok(Json.toJson(Scoreboard(0)))
Ok(Json.toJson(None))
}
}
6 changes: 4 additions & 2 deletions election-api-scala/app/model/PartyResult.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ case class ConstituencyResult(id: Int, name: String, seqNo: Int, partyResults: S

case class ApiResponse (error: String, message: String)


case class Scoreboard(declared:Int)
// TODO: this class should hold:
// - the overall winner (if there is one)
// - the seats that each party wins in Parliament
case class Scoreboard(winner: String)
5 changes: 2 additions & 3 deletions election-api-scala/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ version := "1.0-SNAPSHOT"

lazy val root = (project in file(".")).enablePlugins(PlayScala)

scalaVersion := "2.13.6"
scalaVersion := "2.13.14"

libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test

libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.1" % Test
2 changes: 1 addition & 1 deletion election-api-scala/project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.5.2
sbt.version=1.10.1
4 changes: 2 additions & 2 deletions election-api-scala/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.8.8")
addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.11.0")
addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.4")
addSbtPlugin("org.foundweekends.giter8" % "sbt-giter8-scaffold" % "0.16.2")
16 changes: 5 additions & 11 deletions election-api-scala/tasks.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
### Task

The product owner has asked that we implement the scoreboard endpoint.

First version: First Past the Post
#### First Past the Post

For each constituency a winner can be declared:
1. if we have votes for that constituency
2. The winning party is which ever party received a plurality of votes, e.g. whoever receives the most votes
For each constituency a winner can be declared if we have votes for at least one party in that constituency.
The winning party is which ever party received a plurality of votes, e.g. whoever receives the most votes.

Someone wins in the UK if they receive half of the constituency seats in Parliament (325).
So if a party has received 325 or more seats it can be declared the winner overall.
Expand All @@ -16,16 +16,10 @@ The scoreboard should show:
- The seats for each party
- The overall winner (i.e. the party with 325 or more seats) if there is one

There is a case class [Scoreboard](app/model/PartyResult.scala) ready to be extended and an
There is a case class [Scoreboard](app/model/PartyResult.scala) which you should alter to show the above results and an
endpoint controller to put your implementation: [ResultsController](app/controllers/ResultsController.scala). You will also need to complete
the [tests](test/controllers/ResultsControllerSpec.scala) as part of your implementation.

Bonus information for the scoreboard:
- The total votes for each party
- The total share of the vote for each party. So the percentage of votes for each party.


### Possible other implementations

- Absolute majority required. Someone needs 50% + 1 votes or a run off is triggered (check the data that's probably all constituencies)
- Allocate the seats from the total declarations based on % of vote share
50 changes: 19 additions & 31 deletions election-api-scala/test/controllers/ResultsControllerSpec.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package controllers

import akka.stream.Materializer
import model.Scoreboard
import org.scalatestplus.play._
import org.scalatestplus.play.guice._
Expand All @@ -10,7 +9,6 @@ import play.api.libs.json.{Json, OFormat}
import service.MapResultService

class ResultsControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting {
implicit lazy val materializer: Materializer = app.materializer
//TODO: You will need the json format for any classes used within the Scoreboard here
implicit val scoreboardJson: OFormat[Scoreboard] = Json.format[Scoreboard]

Expand All @@ -21,47 +19,37 @@ class ResultsControllerSpec extends PlaySpec with GuiceOneAppPerTest with Inject

"Test first 5 results" in {
val scoreboard = runXResults(5)
scoreboard match {
case Some(sc) => matchScoreboard(scoreboard = sc, LabSeats = 4, LDSeats = 1)
case None => fail("Didn't return a scoreboard")
}
scoreboard must not be empty
// LAB = 4
// LD = 1
// winner = noone
}

"First 100 results" in {
val scoreboard = runXResults(100)
scoreboard match {
case Some(sc) => matchScoreboard(scoreboard = sc, LabSeats = 56, LDSeats = 12, ConSeats = 31)
case None => fail("Didn't return a scoreboard")
}
scoreboard must not be empty
// LD == 12
// LAB == 56
// CON == 31
// winner = noone
}

"First 554 results" in {
val scoreboard = runXResults(554)
scoreboard match {
case Some(sc) => matchScoreboard(scoreboard = sc, LabSeats = 325, LDSeats = 52, ConSeats = 167, winner = Some("LAB"))
case None => fail("Didn't return a scoreboard")
}
scoreboard must not be empty
// LD == 52
// LAB = 325
// CON = 167
// winner = LAB
}

"All results" in {
val scoreboard = runXResults(650)
scoreboard match {
case Some(sc) => matchScoreboard(scoreboard = sc, LabSeats = 349, LDSeats = 62, ConSeats = 210, winner = Some("LAB"))
case None => fail("Didn't return a scoreboard")
}
}

def matchScoreboard(scoreboard: Scoreboard, LabSeats: Int = 0,
LDSeats: Int = 0, ConSeats: Int = 0, winner: Option[String] = None) {
var ld, lab, con = 0

//TODO: set the seats by party

ld mustEqual LDSeats
lab mustEqual LabSeats
con mustEqual ConSeats
// something mustEqual winner
fail("Implement me")
scoreboard must not be empty
// LD == 62
// LAB == 349
// CON == 210
// winner = LAB
}

def runXResults(number: Int): Option[Scoreboard] = {
Expand Down
Loading