import test from 'zopf'
import proxyquire from 'proxyquire'
import assign from 'object-assign'
import Immutable from 'seamless-immutable'
import Promise from 'bluebird'

import http from './stubs/http'
import app_store from './stubs/app-store'
import install_store from './stubs/install-store'
import electron from './stubs/electron'

let typical_install = Immutable({
  _id: 42,
  upload_id: 11,
  uploads: { '11': { id: 11, size: 512 } }
})

let upload_response = Immutable({
  url: 'http://example.org/game.zip'
})

let setup = (t) => {
  let fs = {
    lstatAsync: () => Promise.reject()
  }
  let client = app_store.get_current_user()

  let stubs = assign({
    '../stores/install-store': install_store,
    '../stores/app-store': app_store,
    '../util/http': http,
    '../util/fs': fs
  }, electron)

  let download = proxyquire('../app/tasks/download', stubs)
  return {download, client, fs, http}
}

test('download validates upload_id', t => {
  let {download} = setup(t)
  let install = typical_install.merge({upload_id: 22})
  t.stub(install_store, 'get_install').resolves(install)
  return t.rejects(download.start({id: 42}))
})

test('download validates upload in list', t => {
  let {download} = setup(t)
  return t.rejects(download.start({id: 42}))
})

test('download downloads free game', t => {
  let {download, client} = setup(t)
  let install = typical_install
  t.stub(install_store, 'get_install').resolves(install)
  t.stub(client, 'download_upload').resolves(upload_response)
  return download.start({id: 42})
})

test('download downloads paid game', t => {
  let {download, client} = setup(t)
  let install = typical_install.merge({key: {id: 'abacus'}})
  t.stub(install_store, 'get_install').resolves(install)
  t.stub(client, 'download_upload_with_key').resolves(upload_response)
  return download.start({id: 42})
})

test('download skips if already complete', t => {
  let {download, client, fs} = setup(t)
  t.stub(install_store, 'get_install').resolves(typical_install)
  t.stub(client, 'download_upload').resolves(upload_response)
  t.stub(fs, 'lstatAsync').resolves({size: 512})
  return t.rejects(download.start({id: 42}))
})

test('download resumes', t => {
  let {download, client, fs, http} = setup(t)
  t.stub(install_store, 'get_install').resolves(typical_install)
  t.stub(client, 'download_upload').resolves(upload_response)
  t.stub(fs, 'lstatAsync').resolves({size: 256})
  let mock = t.mock(http)
  mock.expects('request').calledWith({})
  return download.start({id: 42})
})

@@ -923,28 +923,8 @@
 load
- validates upload_id
 ', t
@@ -944,29 +944,89 @@
 download
-%7D = setup(t)%0A
+, client, fs, http%7D = setup(t)%0A%0A  t.case('validates upload_id', t =%3E %7B%0A  
   let in
@@ -1072,16 +1072,18 @@
 d: 22%7D)%0A
+  
   t.stub
@@ -1131,16 +1131,18 @@
 nstall)%0A
+  
   return
@@ -1178,35 +1178,32 @@
 : 42%7D))%0A
+  
 %7D)%0A%0A
-test('download 
+  t.case('
 validate
@@ -1234,34 +1234,8 @@
 %7B%0A  
-let %7Bdownload%7D = setup(t)%0A
   re
@@ -1275,35 +1275,32 @@
 : 42%7D))%0A
+  
 %7D)%0A%0A
-test('download 
+  t.case('
 download
@@ -1326,42 +1326,8 @@
 %7B%0A  
-let %7Bdownload, client%7D = setup(t)%0A
   le
@@ -1354,16 +1354,18 @@
 install%0A
+  
   t.stub
@@ -1405,32 +1405,34 @@
 solves(install)%0A
+  
   t.stub(client,
@@ -1469,32 +1469,34 @@
 pload_response)%0A
+  
   return downloa
@@ -1513,35 +1513,32 @@
 d: 42%7D)%0A
+  
 %7D)%0A%0A
-test
+  t.case
 ('
-download 
 download
@@ -1564,42 +1564,8 @@
 %7B%0A  
-let %7Bdownload, client%7D = setup(t)%0A
   le
@@ -1621,16 +1621,18 @@
 cus'%7D%7D)%0A
+  
   t.stub
@@ -1674,32 +1674,34 @@
 lves(install)%0A  
+ 
+ 
 t.stub(client, '
@@ -1753,16 +1753,18 @@
 sponse)%0A
+  
   return
@@ -1793,102 +1793,55 @@
 2%7D)%0A
+  
 %7D)%0A%0A
-test('download skips if already complete', t =%3E %7B%0A  let %7Bdownload, client, fs%7D = setup(t)%0A
+  t.case('skips when complete', t =%3E %7B%0A  
   t.
@@ -1893,32 +1893,34 @@
 ypical_install)%0A
+  
   t.stub(client,
@@ -1959,32 +1959,34 @@
 oad_response)%0A  
+ 
+ 
 t.stub(fs, 'lsta
@@ -2016,16 +2016,18 @@
 : 512%7D)%0A
+  
   return
@@ -2067,27 +2067,24 @@
 %7D))%0A
+  
 %7D)%0A%0A
-test('download 
+  t.case('
 resu
@@ -2102,52 +2102,8 @@
 %7B%0A  
-let %7Bdownload, client, fs, http%7D = setup(t)%0A
   t.
@@ -2163,16 +2163,18 @@
 nstall)%0A
+  
   t.stub
@@ -2229,16 +2229,18 @@
 onse)%0A  
+ 
+ 
 t.stub(f
@@ -2278,16 +2278,18 @@
 : 256%7D)%0A
+  
   let mo
@@ -2306,16 +2306,18 @@
 k(http)%0A
+  
   mock.e
@@ -2347,24 +2347,26 @@
 dWith(%7B%7D)%0A  
+ 
+ 
 return downl
@@ -2385,11 +2385,16 @@
 d: 42%7D)%0A
+  %7D)%0A
 %7D)%0A

Use t.case for download spec