                                      :account-id
                                      :shares-purchased
                                      :shares-owned])
-                    (lots/select-by-commodity-id storage-spec (:id commodity)))]
+                    (lots/select-by-commodity-id (env :db) (:id commodity)))]
     (is (= expected actual) "The lot can be retrieved from the database")))
 
 (deftest a-purchase-creates-a-price-record
-  (let [context (serialization/realize storage-spec purchase-context)
-        ira (find-account context "IRA")
-        commodity (find-commodity context "AAPL")
-        _ (trading/buy storage-spec {:commodity-id (:id commodity)
+  (let [context (serialization/realize (env :db) purchase-context)
+        ira (find-account context "IRA")
+        commodity (find-commodity context "AAPL")
+        _ (trading/buy (env :db) {:commodity-id (:id commodity)
                                      :account-id (:id ira)
                                      :trade-date (t/local-date 2016 1 2)
                                      :shares 100M

        "The validation message indicates the error")))

(deftest purchase-requires-a-value
  (let [context (serialization/realize storage-spec purchase-context)
        ira (find-account context "IRA")
        commodity (find-commodity context "AAPL")
        result (trading/buy storage-spec (-> context
                                             (purchase-attributes)
                                             (dissoc :value)))]
    (is (= ["Value is required"]

        (is (= expected actual)
            "The entity settings are updated with default account ids")))))

(deftest sell-a-commodity-for-a-loss
  (let [context (serialization/realize (env :db) sale-context)
        commodity (find-commodity context "AAPL")
        attr (assoc (sale-attributes context) :value 200M) ; 25 shares, $50 loss
        {:keys [lots transaction price]} (trading/sell (env :db) attr)
        ira (find-account context "IRA")
        lot (lots/find-by (env :db) {:commodity-id (:id commodity)
                                     :account-id (:id ira)
                                     :purchase-date (t/local-date 2016 3 2)})]
    (is (= 8M (:price price))
        "The result contains the correct price")
    (is (empty? (validation/error-messages price))
        "The price is valid")
    (is lots "The result contains the lots affected")
    (doseq [lot lots]
      (is (empty? (validation/error-messages lot))
          "Each lot is valid"))
    (is (= 75M (:shares-owned lot))
        "The shares-owned value of the original lot is updated")
    (is transaction "The result contains the transaction record")
    (is (empty? (validation/error-messages transaction))
        "The transaction is valid")
    (if-let [item (->> (:items transaction)
                (filter #(= (:lt-capital-loss-account-id attr)
                           (:account-id %)))
                first)]
      (is (selective= {:action :debit
                       :quantity 50M}
                      item)
          "The correct capital loss is recored")
      (is false "A capital loss item is created"))))

(deftest sell-a-commodity-with-a-fee
  (let [context (serialization/realize (env :db) sale-context)
        ira (find-account context "IRA")
        inv-exp (->> context
                     :accounts
                     (filter #(= "Investment Expenses" (:name %)))
                     first)]
    (trading/sell (env :db)
                  (-> context
                      sale-attributes
                      (assoc :fee 5M
                             :fee-account-id (:id inv-exp))))
    (is (= 1370M (:quantity (accounts/reload (env :db) ira)))
        "The investment account balance reflects the fee")
    (is (= 5M (:quantity (accounts/reload (env :db) inv-exp)))
        "The investment fee account balance reflects the fee")))

(deftest sales-requires-a-trade-date
  (let [context (serialization/realize (env :db) sale-context)
        result (trading/sell (env :db) (-> context
                                              sale-attributes
                                              (dissoc :trade-date)))]
    (is (= ["Trade date is required"]
