Skip to content

Commit

Permalink
refactored tests, seitenanzeige implementiert
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanPenndorf committed Nov 9, 2013
1 parent 7776133 commit 9bba3ff
Show file tree
Hide file tree
Showing 17 changed files with 277 additions and 43 deletions.
19 changes: 19 additions & 0 deletions app/assets/stylesheets/main.less
Expand Up @@ -117,6 +117,25 @@ img.foto {
}
}

#fotoalbum-seiten-blaetterer{
ul {
list-style: none;
display: block;
margin-left: auto;
margin-right: auto;
width: 240px;
}
li {
display: inline;
font-weight: bold;
}
.seitennummer {
color: @default-color;
font-weight: normal;
}
}


#footer {
clear: both;
text-align: center;
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/FotoVorfuehrer.scala
Expand Up @@ -35,7 +35,7 @@ class FotoVorfuehrer @Inject()(
Ok(views.html.fotoalben(verwalter.alleFotoalben()))
}

def fotoalbum(besitzerName: BenutzerName): Action[AnyContent] = StackAction{ implicit request =>
def fotoalbum(besitzerName: BenutzerName, seite: Int): Action[AnyContent] = StackAction{ implicit request =>
val findeFotoSeite = scala.concurrent.Future {
gästeliste.findeGastMitName(besitzerName)
}.map {
Expand All @@ -45,7 +45,7 @@ class FotoVorfuehrer @Inject()(

Async {
findeFotoSeite.map {
case Some(fotoalbum) => Ok(views.html.fotoalbumSeite(FotoalbumSeite(fotoalbum)))
case Some(fotoalbum) => Ok(views.html.fotoalbumSeite(FotoalbumSeite(fotoalbum, seite)))
case None => NotFound("Ungültiges Album")
}
}
Expand Down
19 changes: 16 additions & 3 deletions app/model/Fotoalbum.scala
Expand Up @@ -15,6 +15,10 @@ case class Fotoalbum(
anzahlFotos: Long
) {

val itemsPerPage = 20

val anzahlSeiten = seiteVonPosition(anzahlFotos)

def fotoMitPosition(position: Long): Option[Foto] = {
if(position < 1) {
None
Expand Down Expand Up @@ -45,20 +49,29 @@ case class Fotoalbum(
fotoMitPosition(prevPos).map( _=> prevPos)
}

def alleFotos: Seq[model.Foto] = {
def alleFotosAufSeite(seite: Int): Seq[model.Foto] = {

DB.withConnection { implicit connection =>
SQL(
"""
SELECT id,besitzer,foto,position FROM fotos f
WHERE f.besitzer = {besitzerId}
LIMIT 45
ORDER BY position
LIMIT {offset},{anzahlFotosAufSeite}
"""
).on(
'besitzerId -> besitzer.id
'besitzerId -> besitzer.id,
'offset -> ( (seite - 1) * itemsPerPage),
'anzahlFotosAufSeite -> itemsPerPage
).as(Foto.simple +)
}
}

def seiteVon(foto: Foto): Int = seiteVonPosition(foto.position)

private def seiteVonPosition(position: Long): Int = (position/itemsPerPage).toInt +
(if(position % itemsPerPage > 0) 1 else 0)

}

object Fotoalbum {
Expand Down
13 changes: 6 additions & 7 deletions app/viewmodel/FotoalbumSeite.scala
@@ -1,16 +1,15 @@
package viewmodel

import model.Benutzer
import model.Fotoalbum

/**
*
* @author Stefan Penndorf <stefan@cyphoria.net>
*/
case class FotoalbumSeite(besitzer: Benutzer,
fotos: Seq[model.Foto])
case class FotoalbumSeite(album: Fotoalbum,
seite: Int) {

val besitzer = album.besitzer
val fotos = album alleFotosAufSeite seite

object FotoalbumSeite {
def apply(album: model.Fotoalbum) = {
new FotoalbumSeite(album.besitzer, album.alleFotos)
}
}
2 changes: 1 addition & 1 deletion app/views/foto.scala.html
Expand Up @@ -16,7 +16,7 @@
&lt;&lt;&lt; Zur&uuml;ck
}
&nbsp;|&nbsp;
<a id="uebersicht" href="@routes.FotoVorfuehrer.fotoalbum(album.besitzer.name)">Übersicht</a>
<a id="uebersicht" href="@routes.FotoVorfuehrer.fotoalbum(album.besitzer.name, album.seiteVon(foto))">Übersicht</a>
&nbsp;|&nbsp;
@album.naechstePosition(foto).map { pos =>
<a id="naechstesBild" href="@routes.FotoVorfuehrer.fotoalbumEinzelfoto(album.besitzer.name, pos)">Weiter &gt;&gt;&gt;</a>
Expand Down
29 changes: 29 additions & 0 deletions app/views/fotoalbumSeite.scala.html
Expand Up @@ -7,7 +7,36 @@
Fotoalbum von @fotoalbumSeite.besitzer.name.vorname
}

@lowbound() = @{
(fotoalbumSeite.seite - 3).max(1)
}

@highbound() = @{
(fotoalbumSeite.seite + 3).min(fotoalbumSeite.album.anzahlSeiten)
}

@main(heading=heading.toString) {
<div id="fotoalbum-seiten-blaetterer">
<ul>
@if(fotoalbumSeite.seite == 1){
<li>&laquo;</li>
<li>&lt;</li>
} else {
<li><a id="ersteSeite" href="@routes.FotoVorfuehrer.fotoalbum(fotoalbumSeite.besitzer.name, 1)">&laquo;</a></li>
<li><a id="vorhergehendeSeite" href="@routes.FotoVorfuehrer.fotoalbum(fotoalbumSeite.besitzer.name, fotoalbumSeite.seite-1)">&lt;</a></li>
}

<li class="seitennummer">Seite @fotoalbumSeite.seite von @fotoalbumSeite.album.anzahlSeiten</li>

@if(fotoalbumSeite.seite == fotoalbumSeite.album.anzahlSeiten) {
<li>&gt;</li>
<li>&raquo;</li>
} else {
<li><a id="naechsteSeite" href="@routes.FotoVorfuehrer.fotoalbum(fotoalbumSeite.besitzer.name, fotoalbumSeite.seite+1)">&gt;</a></li>
<li><a id="letzteSeite" href="@routes.FotoVorfuehrer.fotoalbum(fotoalbumSeite.besitzer.name, fotoalbumSeite.album.anzahlSeiten)">&raquo;</a></li>
}
</ul>
</div>
<div id="fotoalbum-seite">
@for(foto <- fotoalbumSeite.fotos) {
<div>
Expand Down
2 changes: 1 addition & 1 deletion conf/routes
Expand Up @@ -22,7 +22,7 @@ GET /impressum controllers.Application.impressum
GET /viparea controllers.VipArea.viparea
GET /fotoalben @controllers.FotoVorfuehrer.fotoalben
POST /fotoalben @controllers.FotoVorfuehrer.hochladen
GET /fotoalbum/:besitzer @controllers.FotoVorfuehrer.fotoalbum(besitzer: model.BenutzerName)
GET /fotoalbum/:besitzer @controllers.FotoVorfuehrer.fotoalbum(besitzer: model.BenutzerName, seite: Int ?= 1)
GET /fotoalbum/:besitzer/foto @controllers.FotoVorfuehrer.fotoalbumEinzelfoto(besitzer: model.BenutzerName, fotoPosition: Long = 1)
GET /fotoalbum/:besitzer/foto/$fotoPosition<[0-9]+> @controllers.FotoVorfuehrer.fotoalbumEinzelfoto(besitzer: model.BenutzerName, fotoPosition: Long)
GET /foto/:id @controllers.FotoVorfuehrer.foto(id: Long)
Expand Down
47 changes: 43 additions & 4 deletions test/net/cyphoria/weddingapp/model/FotoalbumTest.scala
Expand Up @@ -16,6 +16,10 @@ class FotoalbumTest extends Specification {
val zweitesFoto: Foto = Foto(Id(2), JPEG_IMAGE_CONTENT, 2)
val drittesFoto: Foto = Foto(Id(3), PNG_IMAGE_CONTENT, 3)

val einundzwanzigstesFoto: Foto = Foto(Id(21), JPEG_IMAGE_CONTENT, 21)
val zweiundzwanzigstesFoto: Foto = Foto(Id(22), JPEG_IMAGE_CONTENT, 22)


"Fotoalbum eines Gastes" should {

"das erste Foto zurück geben" in DatenbankMit("einemGastMitEinemFoto") {
Expand Down Expand Up @@ -54,14 +58,49 @@ class FotoalbumTest extends Specification {
einGast.fotoalbum.get.vorhergehendePosition(zweitesFoto) must beSome(1)
}

"ein Foto bereitstellen koennen" in DatenbankMit("einemGastMitEinemFoto") {
einGast.fotoalbum.get.alleFotos must beEqualTo(Seq(erstesFoto))
"alle Fotos der ersten Seite bereitstellen koennen" in DatenbankMit("einemGastMitDreiFotos") {
einGast.fotoalbum.get.alleFotosAufSeite(1) must beEqualTo(Seq(erstesFoto, zweitesFoto, drittesFoto))
}

"alle Fotos der zweiten Seite bereitstellen koennen" in DatenbankMit("einemGastMitZweiUndZwanzigFotos") {
einGast.fotoalbum.get.alleFotosAufSeite(2) must beEqualTo(Seq(einundzwanzigstesFoto, zweiundzwanzigstesFoto))
}

"alle 20 Fotos pro Seite bereitstellen koennen" in DatenbankMit("einemGastMitZweiUndZwanzigFotos") {
einGast.fotoalbum.get.alleFotosAufSeite(1) must haveSize(20)
}

"Seite 1 für ein Foto auf der ersten Seite bestimmen" in DatenbankMit("einemGastMitEinemFoto") {
einGast.fotoalbum.get.seiteVon(erstesFoto) must beEqualTo(1)
}

"Seite 2 für ein Foto auf der zweiten Seite bestimmen" in DatenbankMit("einemGastMitEinemFoto") {
einGast.fotoalbum.get.seiteVon(einundzwanzigstesFoto) must beEqualTo(2)
}

"alle Fotos in richtiger Reihenfolge bereitstellen koennen" in DatenbankMit("einemGastMitDreiFotos") {
einGast.fotoalbum.get.alleFotos must beEqualTo(Seq(erstesFoto, zweitesFoto, drittesFoto))
"Seite 1 für das zwanzigste Foto bestimmen" in DatenbankMit("einemGastMitZweiUndZwanzigFotos") {
val album = einGast.fotoalbum.get
album.seiteVon(album.fotoMitPosition(20).get) must beEqualTo(1)
}

"Seite 2 für das einundzwanzigste Foto bestimmen" in DatenbankMit("einemGastMitZweiUndZwanzigFotos") {
val album = einGast.fotoalbum.get
album.seiteVon(album.fotoMitPosition(21).get) must beEqualTo(2)
}

"mit einem Bild eine Seite haben" in DatenbankMit("einemGastMitEinemFoto") {
einGast.fotoalbum.get.anzahlSeiten must beEqualTo(1)
}

"mit drei Bildern eine Seite haben" in DatenbankMit("einemGastMitDreiFotos") {
einGast.fotoalbum.get.anzahlSeiten must beEqualTo(1)
}

"mit zweiundzwanzig Bilden zwei Seiten haben" in DatenbankMit("einemGastMitZweiUndZwanzigFotos") {
einGast.fotoalbum.get.anzahlSeiten must beEqualTo(2)
}


}

val verwalter = new PersistenterFotoalbenVerwalter()
Expand Down
20 changes: 18 additions & 2 deletions test/net/cyphoria/weddingapp/specification/FotoalbumSchritte.scala
Expand Up @@ -31,6 +31,13 @@ class FotoalbumSchritte extends Schritte with ScalaDsl with DE with Browser {
Seq(bild1, bild2, bild3).foreach({cp => fotoalben upload cp; fotoalben go()})
}

Angenommen("""^Kerstin hat 21 Bilder hochgeladen$"""){ () =>
startseite isAt()
startseite geheZuFotoalbum()

(Seq.fill(20)(bild2) :+ bild1).foreach({cp => fotoalben upload cp; fotoalben go()})
}

Angenommen("""^Kerstin ruft das erste Foto auf$"""){ () =>
fotoalben oeffneAlbumVon "Kerstin"
fotoalben waehleFoto 1
Expand All @@ -41,17 +48,21 @@ class FotoalbumSchritte extends Schritte with ScalaDsl with DE with Browser {
}

Wenn("""^sie ein Bild weiter blättert$"""){ () =>
fotoalben naechstesBild()
fotoalben naechstesFoto()
}

Wenn("""^sie ein Bild zurück blättert$"""){ () =>
fotoalben vorhergehendesBild()
fotoalben vorhergehendesFoto()
}

Wenn("""sie ihr Fotoalbum aufruft"""){ () =>
fotoalben oeffneAlbumVon "Kerstin"
}

Wenn("""^auf die zweite Seite blättert$"""){ () =>
fotoalben naechsteSeite
}

Dann("""^wird ein Fotoalbum für sie erstellt$"""){ () =>
fotoalben oeffneAlbumVon "Kerstin"
}
Expand All @@ -68,4 +79,9 @@ class FotoalbumSchritte extends Schritte with ScalaDsl with DE with Browser {
fotoalben zeigtSeiteMit(anzahlBilder = 3)
}

Dann("""^kann sie die zweite Seite ihres Fotoalbums sehen$"""){ () =>
fotoalben zeigtSeiteMit(anzahlBilder = 1)
fotoalben zeigtBild bild1
}

}
Expand Up @@ -13,29 +13,27 @@ import javax.imageio.ImageIO
import net.cyphoria.weddingapp.imagecompare.scalatest.ImageCompareMatchers
import java.io.File
import net.cyphoria.weddingapp.imagecompare.FileDownloader
import org.fluentlenium.core.annotation.Page


/**
*
* @author Stefan Penndorf <stefan@cyphoria.net>
*/
class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMatchers {

class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMatchers with NavigationHelpers {

var bildDatei: FluentWebElement = null
var starteHochladen: FluentWebElement = null

def oeffneAlbumVon(s: String) {
$(s"""#fotoalben a[href*="$s"]""").first.click
@Page
var fotoalbum: FotoalbumSeiteSeite = null

await().atMost(50, TimeUnit.SECONDS).until(new Predicate[WebDriver] {
def apply(p1: WebDriver): Boolean = {
val heading: String = $("h1").getText
heading != null && heading.contains(s"""Fotoalbum von $s""")
}
})
def oeffneAlbumVon(besitzer: String) {
$(s"""#fotoalben a[href*="$besitzer"]""").first.click

$("img").first() should be ('displayed)
await().atMost(3, TimeUnit.SECONDS).untilPage(fotoalbum).isAt()
fotoalbum.isAt(besitzer)
fotoalbum
}

def upload(s: Resource) {
Expand Down Expand Up @@ -69,15 +67,9 @@ class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMat
ImageIO.read(target)
}

def naechstesBild() = {
await().atMost(3, TimeUnit.SECONDS).until("#naechstesBild").isPresent
$("#naechstesBild").first.click
}
def naechstesFoto() = warteAufUndKlickeDann("#naechstesBild")

def vorhergehendesBild() = {
await().atMost(3, TimeUnit.SECONDS).until("#vorhergehendesBild").isPresent
$("#vorhergehendesBild").first.click
}
def vorhergehendesFoto() = warteAufUndKlickeDann("#vorhergehendesBild")

def waehleFoto(i: Int) = {
$("img").get(i-1).click()
Expand All @@ -94,6 +86,7 @@ class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMat
await().atMost(3, TimeUnit.SECONDS).until("img").hasSize(anzahlBilder)
}

def naechsteSeite = warteAufUndKlickeDann("#naechsteSeite")

override def getUrl: String = "/fotoalben"

Expand Down
@@ -0,0 +1,28 @@
package net.cyphoria.weddingapp.specification.seiten

import org.fluentlenium.core.FluentPage
import org.scalatest.matchers.ShouldMatchers
import java.util.concurrent.TimeUnit

/**
* Seitenrepräsentation einer Seite eines Fotoalbums eines Benutzers.
*
* @author Stefan Penndorf <stefan@cyphoria.net>
*/
class FotoalbumSeiteSeite extends FluentPage with ShouldMatchers with ZeigtFotoPruefer with NavigationHelpers {


override def getUrl: String = "/fotoalbum/<Besitzer>"

override def isAt() = isAt("")

def isAt(besitzer: String) {
await().atMost(5, TimeUnit.SECONDS).until("h1").withText().contains(s"""Fotoalbum von $besitzer""").isPresent

$("img").first() should be ('displayed)
}




}
@@ -0,0 +1,20 @@
package net.cyphoria.weddingapp.specification.seiten

import org.fluentlenium.core.FluentPage
import java.util.concurrent.TimeUnit

/**
*
* @author Stefan Penndorf <stefan@cyphoria.net>
*/
trait NavigationHelpers {
self: FluentPage =>

def warteAufUndKlickeDann(element: String) = {
await().atMost(3, TimeUnit.SECONDS).until(element).isPresent
$(element).first.click
}



}

0 comments on commit 9bba3ff

Please sign in to comment.