/salat-core/src/test/scala/com/novus/salat/test/dao/ChildCollectionSpec.scala

https://github.com/ornicar/salat · Scala · 155 lines · 107 code · 23 blank · 25 comment · 0 complexity · d9997b6f229826e9d0ae45a213e7f955 MD5 · raw file

  1. /** Copyright (c) 2010, 2011 Novus Partners, Inc. <http://novus.com>
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. *
  15. * For questions and comments about this product, please see the project page at:
  16. *
  17. * http://github.com/novus/salat
  18. *
  19. */
  20. package com.novus.salat.test.dao
  21. import com.novus.salat.test._
  22. import com.novus.salat._
  23. import com.novus.salat.global._
  24. import com.mongodb.casbah.Imports._
  25. import org.specs2.specification.Scope
  26. import com.novus.salat.test.dao._
  27. import org.scala_tools.time.Imports._
  28. import org.joda.time.DateTimeConstants._
  29. import org.joda.time.DateMidnight
  30. import com.mongodb.casbah.commons.{ MongoDBList, MongoDBObject }
  31. class ChildCollectionSpec extends SalatSpec {
  32. // force spec to run sequentially
  33. override def is = args(sequential = true) ^ super.is
  34. "SalatDAO's child collection trait" should {
  35. "support finding children by typed parent id" in new parentChildContext {
  36. ParentDAO.children.findByParentId(parent1.id).toList must contain(child1Parent1, child2Parent1, child3Parent1).only
  37. ParentDAO.children.findByParentId(parent2.id).toList must contain(child1Parent2, child2Parent2).only
  38. ParentDAO.children.findByParentId(parent3.id).toList must beEmpty
  39. }
  40. "support finding children by parent id with key includes" in new parentChildContext {
  41. ParentDAO.children.findByParentId(parentId = parent1.id, query = MongoDBObject(), keys = MongoDBObject("parentId" -> 1, "y" -> 1)).toList must contain(
  42. child1Parent1.copy(x = "", childInfo = ChildInfo()),
  43. child2Parent1.copy(x = "", childInfo = ChildInfo()),
  44. child3Parent1.copy(x = "", childInfo = ChildInfo())).only
  45. ParentDAO.children.findByParentId(parentId = parent2.id, query = MongoDBObject(), keys = MongoDBObject("parentId" -> 1, "y" -> 1)).toList must contain(
  46. child1Parent2.copy(x = "", childInfo = ChildInfo()),
  47. child2Parent2.copy(x = "", childInfo = ChildInfo())).only
  48. ParentDAO.children.findByParentId(parent3.id).toList must beEmpty
  49. }
  50. "support finding child IDs by typed parent id" in new parentChildContext {
  51. ParentDAO.children.idsForParentId(parent1.id).toList must contain(1, 2, 3).only
  52. ParentDAO.children.idsForParentId(parent2.id).toList must contain(4, 5).only
  53. ParentDAO.children.idsForParentId(parent3.id).toList must beEmpty
  54. }
  55. "support updating children by typed parent id" in new parentChildContext {
  56. val newLastUpdated = new DateMidnight(1812, FEBRUARY, 7).toDateTime
  57. val updateQuery = MongoDBObject("$set" -> MongoDBObject("childInfo.lastUpdated" -> newLastUpdated))
  58. val cr = ParentDAO.children.updateByParentId(parent1.id, updateQuery, false, true)
  59. // number of children is unchanged
  60. ParentDAO.children.collection.count must_== 5L
  61. // children of parent1 are updated as expected
  62. ParentDAO.children.findByParentId(parent1.id).toList must contain(
  63. child1Parent1.copy(childInfo = ChildInfo(lastUpdated = newLastUpdated)),
  64. child2Parent1.copy(childInfo = ChildInfo(lastUpdated = newLastUpdated)),
  65. child3Parent1.copy(childInfo = ChildInfo(lastUpdated = newLastUpdated))).only
  66. // child collection is otherwise unchanged
  67. ParentDAO.children.findByParentId(parent2.id).toList must contain(child1Parent2, child2Parent2).only
  68. ParentDAO.children.findByParentId(parent3.id).toList must beEmpty
  69. }
  70. "support removing children by parent id" in new parentChildContext {
  71. val cr = ParentDAO.children.removeByParentId(parent1.id)
  72. // three children of parent1 have been removed from the child collection, overall count is reduced
  73. ParentDAO.children.findByParentId(parent1.id).toList must beEmpty
  74. ParentDAO.children.collection.count must_== 2L
  75. // child collection is otherwise unchanged
  76. ParentDAO.children.findByParentId(parent2.id).toList must contain(child1Parent2, child2Parent2).only
  77. ParentDAO.children.findByParentId(parent3.id).toList must beEmpty
  78. }
  79. "support primitive projections by parent id" in new parentChildContext {
  80. ParentDAO.children.primitiveProjectionsByParentId[String](parent1.id, "x") must contain("child1Parent1",
  81. "child2Parent1", "child3Parent1").only
  82. ParentDAO.children.primitiveProjectionsByParentId[String](parent2.id, "x") must contain("child1Parent2",
  83. "child2Parent2").only
  84. ParentDAO.children.primitiveProjectionsByParentId[String](parent3.id, "x") must beEmpty
  85. }
  86. "support case class projections by parent id" in new parentChildContext {
  87. ParentDAO.children.projectionsByParentId[ChildInfo](parent1.id, "childInfo") must contain(child1Parent1.childInfo,
  88. child2Parent1.childInfo, child3Parent1.childInfo).only
  89. ParentDAO.children.projectionsByParentId[ChildInfo](parent2.id, "childInfo") must contain(child1Parent2.childInfo,
  90. child2Parent2.childInfo).only
  91. ParentDAO.children.projectionsByParentId[ChildInfo](parent3.id, "childInfo") must beEmpty
  92. }
  93. "support counting by parent id" in new parentChildContext {
  94. ParentDAO.children.countByParentId(parent1.id) must_== 3L
  95. ParentDAO.children.countByParentId(parent2.id) must_== 2L
  96. ParentDAO.children.countByParentId(parent3.id) must_== 0L
  97. }
  98. "support counting by parent id with fields" in new parentChildContext {
  99. ParentDAO.children.countByParentId(parentId = parent1.id,
  100. fieldsThatMustExist = List("x")) must_== 3L
  101. ParentDAO.children.countByParentId(parentId = parent1.id,
  102. fieldsThatMustExist = List("x"),
  103. fieldsThatMustNotExist = List("y")) must_== 2L
  104. ParentDAO.children.countByParentId(parentId = parent1.id,
  105. fieldsThatMustExist = List("x", "y")) must_== 1L
  106. }
  107. }
  108. trait parentChildContext extends Scope {
  109. log.debug("before: dropping %s", ParentDAO.collection.getFullName())
  110. ParentDAO.collection.drop()
  111. ParentDAO.collection.count must_== 0L
  112. val childDAO = ParentDAO.children
  113. log.debug("before: dropping %s", childDAO.collection.getFullName())
  114. childDAO.collection.drop()
  115. childDAO.collection.count must_== 0L
  116. val parent1 = Parent(name = "parent1")
  117. val parent2 = Parent(name = "parent2")
  118. val parent3 = Parent(name = "parent3")
  119. val _ids = ParentDAO.insert(parent1, parent2, parent3)
  120. _ids must contain(Option(parent1.id), Option(parent2.id), Option(parent3.id)).only
  121. ParentDAO.collection.count must_== 3L
  122. val child1Parent1 = Child(id = 1, parentId = parent1.id, x = "child1Parent1", y = Some("child1Parent1"))
  123. val child2Parent1 = Child(id = 2, parentId = parent1.id, x = "child2Parent1")
  124. val child3Parent1 = Child(id = 3, parentId = parent1.id, x = "child3Parent1")
  125. val child1Parent2 = Child(id = 4, parentId = parent2.id, x = "child1Parent2", y = Some("child1Parent2"))
  126. val child2Parent2 = Child(id = 5, parentId = parent2.id, x = "child2Parent2", y = Some("child2Parent2"))
  127. val childIds = ParentDAO.children.insert(child1Parent1, child2Parent1, child3Parent1, child1Parent2, child2Parent2)
  128. childIds must contain(Option(child1Parent1.id), Option(child2Parent1.id), Option(child3Parent1.id),
  129. Option(child1Parent2.id), Option(child2Parent2.id)).only
  130. ParentDAO.children.collection.count must_== 5L
  131. }
  132. }