Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: KyleRogers/wedding-app
base: 61db96aaa8
...
head fork: KyleRogers/wedding-app
compare: 78fc80c54e
  • 3 commits
  • 20 files changed
  • 0 commit comments
  • 1 contributor
Showing with 417 additions and 44 deletions.
  1. +47 −9 app/assets/stylesheets/main.less
  2. +18 −1 app/controllers/FotoVorfuehrer.scala
  3. +27 −0 app/model/Fotoalbum.scala
  4. +15 −0 app/viewmodel/FotoalbumSeite.scala
  5. +4 −2 app/views/foto.scala.html
  6. +1 −1  app/views/fotoalben.scala.html
  7. +49 −0 app/views/fotoalbumSeite.scala.html
  8. +1 −5 app/views/viparea.scala.html
  9. +3 −2 conf/routes
  10. +12 −1 test/net/cyphoria/weddingapp/functional/FotoVorfuehrerControllerTest.scala
  11. +47 −0 test/net/cyphoria/weddingapp/model/FotoalbumTest.scala
  12. +28 −3 test/net/cyphoria/weddingapp/specification/FotoalbumSchritte.scala
  13. +27 −14 test/net/cyphoria/weddingapp/specification/seiten/FotoalbenSeite.scala
  14. +28 −0 test/net/cyphoria/weddingapp/specification/seiten/FotoalbumSeiteSeite.scala
  15. +20 −0 test/net/cyphoria/weddingapp/specification/seiten/NavigationHelpers.scala
  16. +4 −3 test/net/cyphoria/weddingapp/specification/seiten/VipAreaStartSeite.scala
  17. +41 −0 test/net/cyphoria/weddingapp/specification/seiten/ZeigtFotoPruefer.scala
  18. +5 −1 test/net/cyphoria/weddingapp/templates/FotoTemplateTest.scala
  19. +26 −0 test/resources/model/einemGastMitZweiUndZwanzigFotos.dbt
  20. +14 −2 test/resources/net/cyphoria/weddingapp/specification/fotoalbum.feature
View
56 app/assets/stylesheets/main.less
@@ -2,6 +2,7 @@
@default-color: #EE3F00;
@left-bar-width: 150px;
@total-width: 1280px;
+@thumbnail-size: 160px;
body, label, h1, h2, h3, input {
color: @default-color;
@@ -75,15 +76,15 @@ body, label, h1, h2, h3, input {
#foto-blaetterer {
padding-left: 160px;
- padding-top: 20px;
+ padding-top: 20px;
}
#foto-blaetterer p {
- display:block;
- margin-left: auto;
+ display: block;
+ margin-left: auto;
margin-right: auto;
- width:160px;
- font-weight:bold;
+ width: 240px;
+ font-weight: bold;
}
input[type="file"][id="bildDatei"] {
@@ -91,10 +92,47 @@ input[type="file"][id="bildDatei"] {
}
img.foto {
- display:block;
- float:right;
- max-width:620px;
- max-height:620px;
+ display: block;
+ float: right;
+ max-width: 620px;
+ max-height: 620px;
+}
+
+#fotoalbum-seite{
+ div {
+ float: left;
+ margin: 5px;
+ width: @thumbnail-size;
+ height: @thumbnail-size;
+ padding: 0;
+ }
+
+ img.foto {
+ float: none;
+ max-width: @thumbnail-size;
+ max-height: @thumbnail-size;
+ margin: auto;
+ -ms-interpolation-mode: nearest-neighbor;
+ image-rendering: optimizeSpeed;
+ }
+}
+
+#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;
+ }
}
View
19 app/controllers/FotoVorfuehrer.scala
@@ -16,6 +16,7 @@ import model.AlleBilderGueltig
import scala.concurrent.Await
import scala.concurrent.duration.Duration
import java.util.concurrent.TimeUnit
+import viewmodel.FotoalbumSeite
/**
*
@@ -34,7 +35,23 @@ class FotoVorfuehrer @Inject()(
Ok(views.html.fotoalben(verwalter.alleFotoalben()))
}
- def fotoalbum(besitzerName: BenutzerName, fotoPosition: Long = 1): 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 {
+ case Some(besitzer) => besitzer.fotoalbum
+ case None => None
+ }
+
+ Async {
+ findeFotoSeite.map {
+ case Some(fotoalbum) => Ok(views.html.fotoalbumSeite(FotoalbumSeite(fotoalbum, seite)))
+ case None => NotFound("Ungültiges Album")
+ }
+ }
+ }
+
+ def fotoalbumEinzelfoto(besitzerName: BenutzerName, fotoPosition: Long = 1): Action[AnyContent] = StackAction{ implicit request =>
val findFotoalbumTask = scala.concurrent.Future {
gästeliste.findeGastMitName(besitzerName)
}.map {
View
27 app/model/Fotoalbum.scala
@@ -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
@@ -45,6 +49,29 @@ case class Fotoalbum(
fotoMitPosition(prevPos).map( _=> prevPos)
}
+ def alleFotosAufSeite(seite: Int): Seq[model.Foto] = {
+
+ DB.withConnection { implicit connection =>
+ SQL(
+ """
+ SELECT id,besitzer,foto,position FROM fotos f
+ WHERE f.besitzer = {besitzerId}
+ ORDER BY position
+ LIMIT {offset},{anzahlFotosAufSeite}
+ """
+ ).on(
+ '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 {
View
15 app/viewmodel/FotoalbumSeite.scala
@@ -0,0 +1,15 @@
+package viewmodel
+
+import model.Fotoalbum
+
+/**
+ *
+ * @author Stefan Penndorf <stefan@cyphoria.net>
+ */
+case class FotoalbumSeite(album: Fotoalbum,
+ seite: Int) {
+
+ val besitzer = album.besitzer
+ val fotos = album alleFotosAufSeite seite
+
+}
View
6 app/views/foto.scala.html
@@ -11,13 +11,15 @@
<div id="foto-blaetterer">
<p>
@album.vorhergehendePosition(foto).map { pos =>
- <a id="vorhergehendesBild" href="@routes.FotoVorfuehrer.fotoalbum(album.besitzer.name, pos)">&lt;&lt;&lt; Zur&uuml;ck</a>
+ <a id="vorhergehendesBild" href="@routes.FotoVorfuehrer.fotoalbumEinzelfoto(album.besitzer.name, pos)">&lt;&lt;&lt; Zur&uuml;ck</a>
}.getOrElse {
&lt;&lt;&lt; Zur&uuml;ck
}
&nbsp;|&nbsp;
+ <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.fotoalbum(album.besitzer.name, pos)">Weiter &gt;&gt;&gt;</a>
+ <a id="naechstesBild" href="@routes.FotoVorfuehrer.fotoalbumEinzelfoto(album.besitzer.name, pos)">Weiter &gt;&gt;&gt;</a>
}.getOrElse {
Weiter &gt;&gt;&gt;
}
View
2  app/views/fotoalben.scala.html
@@ -47,7 +47,7 @@
<ul id="fotoalben">
@for(fotoalbum<-fotoalben) {
- <li><a href="@routes.FotoVorfuehrer.fotoalbum(fotoalbum.besitzer.name, 1)">@fotoalbum.besitzer.name.vorname (@fotoalbum.anzahlFotos Bilder)</a></li>
+ <li><a href="@routes.FotoVorfuehrer.fotoalbum(fotoalbum.besitzer.name)">@fotoalbum.besitzer.name.vorname (@fotoalbum.anzahlFotos Bilder)</a></li>
}
</ul>
</div>
View
49 app/views/fotoalbumSeite.scala.html
@@ -0,0 +1,49 @@
+@(fotoalbumSeite: viewmodel.FotoalbumSeite)
+
+@import helper._
+@import helper.twitterBootstrap._
+
+@heading = {
+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>
+ <a href="@routes.FotoVorfuehrer.fotoalbumEinzelfoto(fotoalbumSeite.besitzer.name, foto.position)">
+ <img class="foto" src="@routes.FotoVorfuehrer.foto(foto.id.get)">
+ </a>
+ </div>
+ }
+</div>
+}
View
6 app/views/viparea.scala.html
@@ -15,23 +15,19 @@
<p>
Zunächst erstmal: <strong>VIELEN VIELEN DANK!!!</strong>
</p>
-
<p>
Es war ein wunderschöner Tag für uns und wir hatten sehr viel Spaß mit euch! Und natürlich auch nochmal vielen
Dank für die tollen Geschenke! Ihr werdet auch noch Post von uns bekommen, aber ich befürchte, dass dauert noch
einbisschen...
</p>
-
<p>
- Wir haben es endlich geschafft: die <a href="@routes.FotoVorfuehrer.fotoalbum(model.BenutzerName("Stefan","Penndorf"), 1)">Fotos von unserer Hochzeit</a> sind online! Ursprünglich wollten wir sie in
+ Wir haben es endlich geschafft: die <a href="@routes.FotoVorfuehrer.fotoalbumEinzelfoto(model.BenutzerName("Stefan","Penndorf"), 1)">Fotos von unserer Hochzeit</a> sind online! Ursprünglich wollten wir sie in
Originalqualität hochladen aber dafür waren sie dann doch zu groß. Wenn ihr gern bestimmte Bilder im Original
haben möchtet, gebt einfach Bescheid – dann brennen wir sie euch auf CD. Viel Spaß beim anschauen :)
</p>
-
<p>
Wir würden uns sehr freuen, wenn ihr <a href="@routes.FotoVorfuehrer.fotoalben">eure Bilder auch hochladen</a> würdet!
</p>
-
<p>
Ganz liebe Grüße<br/>
Steffi & Stefan
View
5 conf/routes
@@ -22,8 +22,9 @@ 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, fotoPosition: Long = 1)
-GET /fotoalbum/:besitzer/$fotoPosition<[0-9]+> @controllers.FotoVorfuehrer.fotoalbum(besitzer: model.BenutzerName, fotoPosition: Long)
+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)
# ADMIN Area
View
13 test/net/cyphoria/weddingapp/functional/FotoVorfuehrerControllerTest.scala
@@ -58,12 +58,23 @@ class FotoVorfuehrerControllerTest extends Specification with MockFactory {
contentAsBytes(result) must beEqualTo(PNG_IMAGE_CONTENT)
}
- "die Fotoseite mit dem ersten Foto im Album anzeigen" in laufenderAnwendungMitScenario("einemGastMitEinemFoto") {
+ "die erste Seite vom Fotoalbum anzeigen" in laufenderAnwendungMitScenario("einemGastMitDreiFotos") {
val result = route(FakeRequest(GET, "/fotoalbum/Kerstin.Albert").withLoggedIn(config)(einGast.id.get)).get
status(result) must equalTo(OK)
contentAsString(result) must contain("Fotoalbum von Kerstin")
contentAsString(result) must contain("src=\"/foto/1\"")
+ contentAsString(result) must contain("src=\"/foto/2\"")
+ contentAsString(result) must contain("src=\"/foto/3\"")
+ }
+
+
+ "die Fotoseite mit dem ersten Foto im Album anzeigen" in laufenderAnwendungMitScenario("einemGastMitEinemFoto") {
+ val result = route(FakeRequest(GET, "/fotoalbum/Kerstin.Albert/foto").withLoggedIn(config)(einGast.id.get)).get
+
+ status(result) must equalTo(OK)
+ contentAsString(result) must contain("Fotoalbum von Kerstin")
+ contentAsString(result) must contain("src=\"/foto/1\"")
}
View
47 test/net/cyphoria/weddingapp/model/FotoalbumTest.scala
@@ -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") {
@@ -54,6 +58,49 @@ class FotoalbumTest extends Specification {
einGast.fotoalbum.get.vorhergehendePosition(zweitesFoto) must beSome(1)
}
+ "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)
+ }
+
+ "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()
View
31 test/net/cyphoria/weddingapp/specification/FotoalbumSchritte.scala
@@ -31,8 +31,16 @@ class FotoalbumSchritte extends Schritte with ScalaDsl with DE with Browser {
Seq(bild1, bild2, bild3).foreach({cp => fotoalben upload cp; fotoalben go()})
}
- Angenommen("""^Kerstin ruft ihr Fotoalbum auf$"""){ () =>
+ 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
}
Wenn("""^sie ein Bild hochlädt$"""){ () =>
@@ -40,11 +48,19 @@ 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$"""){ () =>
@@ -59,4 +75,13 @@ class FotoalbumSchritte extends Schritte with ScalaDsl with DE with Browser {
fotoalben zeigtBild bild2
}
+ Dann("""^kann sie die erste Seite ihres Fotoalbums mit den drei Bildern sehen$"""){ () =>
+ fotoalben zeigtSeiteMit(anzahlBilder = 3)
+ }
+
+ Dann("""^kann sie die zweite Seite ihres Fotoalbums sehen$"""){ () =>
+ fotoalben zeigtSeiteMit(anzahlBilder = 1)
+ fotoalben zeigtBild bild1
+ }
+
}
View
41 test/net/cyphoria/weddingapp/specification/seiten/FotoalbenSeite.scala
@@ -13,27 +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) {
@@ -54,6 +54,7 @@ class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMat
}
private def aktuellesBild: BufferedImage = {
+ await().atMost(3, TimeUnit.SECONDS).until("img").areDisplayed()
val imageSrc = $("img").first().getAttribute("src")
imageSrc should include("foto")
@@ -66,14 +67,26 @@ class FotoalbenSeite extends FluentPage with ShouldMatchers with ImageCompareMat
ImageIO.read(target)
}
- def naechstesBild() = {
- $("#naechstesBild").first.click
+ def naechstesFoto() = warteAufUndKlickeDann("#naechstesBild")
+
+ def vorhergehendesFoto() = warteAufUndKlickeDann("#vorhergehendesBild")
+
+ def waehleFoto(i: Int) = {
+ $("img").get(i-1).click()
}
- def vorhergehendesBild() = {
- $("#vorhergehendesBild").first.click
+ def zeigtSeiteMit(anzahlBilder: Int) = {
+ await().atMost(10, TimeUnit.SECONDS).until(new Predicate[WebDriver] {
+ def apply(p1: WebDriver): Boolean = {
+ val heading: String = $("h1").getText
+ heading != null && heading.contains("Fotoalbum von")
+ }
+ })
+
+ await().atMost(3, TimeUnit.SECONDS).until("img").hasSize(anzahlBilder)
}
+ def naechsteSeite = warteAufUndKlickeDann("#naechsteSeite")
override def getUrl: String = "/fotoalben"
View
28 test/net/cyphoria/weddingapp/specification/seiten/FotoalbumSeiteSeite.scala
@@ -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)
+ }
+
+
+
+
+}
View
20 test/net/cyphoria/weddingapp/specification/seiten/NavigationHelpers.scala
@@ -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
+ }
+
+
+
+}
View
7 test/net/cyphoria/weddingapp/specification/seiten/VipAreaStartSeite.scala
@@ -3,6 +3,7 @@ package net.cyphoria.weddingapp.specification.seiten
import org.fluentlenium.core.FluentPage
import org.scalatest.matchers.ShouldMatchers
import org.fluentlenium.core.annotation.Page
+import java.util.concurrent.TimeUnit
/**
*
@@ -11,13 +12,13 @@ import org.fluentlenium.core.annotation.Page
class VipAreaStartSeite extends FluentPage with ShouldMatchers {
@Page
- var fotoalbum: FotoalbenSeite = null
+ var fotoalben: FotoalbenSeite = null
def geheZuFotoalbum() {
$("""#navigation a[id="nav-fotoalben"]""").first.click
- fotoalbum isAt()
- fotoalbum
+ await().atMost(3, TimeUnit.SECONDS).untilPage(fotoalben).isAt()
+ fotoalben
}
override def getUrl: String = "/vip"
View
41 test/net/cyphoria/weddingapp/specification/seiten/ZeigtFotoPruefer.scala
@@ -0,0 +1,41 @@
+package net.cyphoria.weddingapp.specification.seiten
+
+import net.cyphoria.weddingapp.imagecompare.scalatest.ImageCompareMatchers
+import org.fluentlenium.core.FluentPage
+import org.springframework.core.io.Resource
+import java.awt.image.BufferedImage
+import java.util.concurrent.TimeUnit
+import java.io.File
+import net.cyphoria.weddingapp.imagecompare.FileDownloader
+import java.net.URL
+import javax.imageio.ImageIO
+import org.scalatest.matchers.ShouldMatchers
+
+/**
+ *
+ * @author Stefan Penndorf <stefan@cyphoria.net>
+ */
+trait ZeigtFotoPruefer extends ImageCompareMatchers {
+ self: FluentPage with ShouldMatchers =>
+
+ final def zeigtFoto(reference: Resource) {
+ aktuellesFoto should beSameImageAs(reference)
+ }
+
+ def bildLocator: String = "img"
+
+ def aktuellesFoto: BufferedImage = {
+ await().atMost(3, TimeUnit.SECONDS).until(bildLocator).areDisplayed()
+ val imageSrc = $(bildLocator).first().getAttribute("src")
+ imageSrc should include("foto")
+
+ val target = File.createTempFile("image", "")
+ // Das ist schlecht und unsicher und sollte durch eine bessere TEMP-Verwaltung ersetzt werden
+ target.deleteOnExit()
+
+ new FileDownloader(getDriver).downloadFile(new URL(imageSrc), target)
+
+ ImageIO.read(target)
+ }
+
+}
View
6 test/net/cyphoria/weddingapp/templates/FotoTemplateTest.scala
@@ -13,7 +13,7 @@ import anorm.Id
class FotoTemplateTest extends Specification {
val foto = running(FakeApplication(additionalConfiguration = inMemoryDatabase())) {
- views.html.foto(Fotoalbum(TERESA, 1), Foto(Id(1), new Array[Byte](11), 1))
+ views.html.foto(Fotoalbum(TERESA, 22), Foto(Id(21), new Array[Byte](11), 21))
}
"Die Fotoansicht" should {
@@ -32,6 +32,10 @@ class FotoTemplateTest extends Specification {
foto.body must not contain("getOrElse")
}
+ "einen Link zur richtigen Seite der Übersicht enthalten" in {
+ foto.body must contain("href=\"/fotoalbum/Teresa.Merfert?seite=2\"")
+ }
+
}
View
26 test/resources/model/einemGastMitZweiUndZwanzigFotos.dbt
@@ -0,0 +1,26 @@
+users:
+- id: 1, email: "kerstin@cyphoria.net", vorname: "Kerstin", nachname: "Albert", passwort: "$2a$10$k5TmtHnitQvFCNAp8SbuFeq1VlhlcSGkXl6JAcwZFX20mRZKgEgm."
+
+fotos:
+- id: 1, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 1
+- id: 2, besitzer: 1, foto: "FFD8FFE000104A464946", position: 2
+- id: 3, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 3
+- id: 4, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 4
+- id: 5, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 5
+- id: 6, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 6
+- id: 7, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 7
+- id: 8, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 8
+- id: 9, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 9
+- id: 10, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 10
+- id: 11, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 11
+- id: 12, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 12
+- id: 13, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 13
+- id: 14, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 14
+- id: 15, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 15
+- id: 16, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 16
+- id: 17, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 17
+- id: 18, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 18
+- id: 19, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 19
+- id: 20, besitzer: 1, foto: "89504E470D0A1A0A4142434445", position: 20
+- id: 21, besitzer: 1, foto: "FFD8FFE000104A464946", position: 21
+- id: 22, besitzer: 1, foto: "FFD8FFE000104A464946", position: 22
View
16 test/resources/net/cyphoria/weddingapp/specification/fotoalbum.feature
@@ -15,13 +15,25 @@ Die Gäste können Fotoalben anschauen und selbst Bilder in ein Fotoalbum hochla
Szenario: Vorblättern im Fotoalbum
Angenommen Kerstin hat drei Bilder hochgeladen
- Und Kerstin ruft ihr Fotoalbum auf
+ Und Kerstin ruft das erste Foto auf
Wenn sie ein Bild weiter blättert
Dann kann sie das zweite Foto anschauen
Szenario: Zurückblättern im Fotoalbum
Angenommen Kerstin hat drei Bilder hochgeladen
- Und Kerstin ruft ihr Fotoalbum auf
+ Und Kerstin ruft das erste Foto auf
Wenn sie ein Bild weiter blättert
Und sie ein Bild zurück blättert
Dann kann sie das erste Foto anschauen
+
+ Szenario: Seiten im Fotoalbum anzeigen
+ Angenommen Kerstin hat drei Bilder hochgeladen
+ Wenn sie ihr Fotoalbum aufruft
+ Dann kann sie die erste Seite ihres Fotoalbums mit den drei Bildern sehen
+
+ @current
+ Szenario: Seiten im Fotoalbum anzeigen
+ Angenommen Kerstin hat 21 Bilder hochgeladen
+ Wenn sie ihr Fotoalbum aufruft
+ Und auf die zweite Seite blättert
+ Dann kann sie die zweite Seite ihres Fotoalbums sehen

No commit comments for this range

Something went wrong with that request. Please try again.