/* eslint-env jest */

import { clone } from 'lodash/lang'

import {
  addTimestampFieldsToItem,
  DatabaseOperation,
  getMockUserContext,
  mockDate,
  setMockDBResponse
} from '../../test-utils'

jest.mock('../../referrals/referralData')
jest.mock('../rewardReferringUser')
jest.mock('../getUserByUsername')

jest.mock('../../databaseClient')

const userContext = getMockUserContext()
const userInfo = {
  id: userContext.id,
  username: userContext.username,
  email: userContext.email
}

beforeAll(() => {
  mockDate.on()
})

afterAll(() => {
  mockDate.off()
})

afterEach(() => {
  jest.resetModules()
})

describe('createUser', () => {
  it('works as expected without referralData', async () => {
    const UserModel = require('../UserModel').default
    const createUser = require('../createUser').default
    const logReferralData = require('../../referrals/referralData').logReferralData
    const rewardReferringUser = require('../rewardReferringUser').default

    const createMethod = jest.spyOn(UserModel, 'create')
    const referralData = null
    const userToCreate = clone(userInfo)

    await createUser(userContext, userToCreate.id,
      userToCreate.username, userToCreate.email, referralData)

    const expectedCreateItem = addTimestampFieldsToItem(userToCreate)
    expect(createMethod)
      .toHaveBeenCalledWith(userContext, expectedCreateItem)
    expect(logReferralData).not.toHaveBeenCalled()
    expect(rewardReferringUser).not.toHaveBeenCalled()
  })

  it('logs referral data and rewards referring user', async () => {
    const UserModel = require('../UserModel').default
    const createUser = require('../createUser').default
    const logReferralData = require('../../referrals/referralData').logReferralData
    const rewardReferringUser = require('../rewardReferringUser').default

    const createMethod = jest.spyOn(UserModel, 'create')
    const userToCreate = clone(userInfo)
    const referralData = {
      referringUser: 'FriendOfMine'
    }

    // Mock fetching the referring user.
    const referringUserId = 'ppooiiuu-151a-4a9a-9289-06906670fd4e'
    jest.mock('../getUserByUsername', () => {
      return () => ({
        id: 'ppooiiuu-151a-4a9a-9289-06906670fd4e'
      })
    })

    await createUser(userContext, userToCreate.id,
      userToCreate.username, userToCreate.email, referralData)

    const expectedCreateItem = addTimestampFieldsToItem(userToCreate)
    expect(createMethod)
      .toHaveBeenCalledWith(userContext, expectedCreateItem)
    expect(logReferralData)
      .toHaveBeenCalledWith(userToCreate.id, referringUserId)
    expect(rewardReferringUser)
      .toHaveBeenCalledWith(referringUserId)
  })

  it('works when referring user does not exist', async () => {
    const UserModel = require('../UserModel').default
    const createUser = require('../createUser').default
    const logReferralData = require('../../referrals/referralData').logReferralData
    const rewardReferringUser = require('../rewardReferringUser').default

    const createMethod = jest.spyOn(UserModel, 'create')
    const userToCreate = clone(userInfo)
    const referralData = {
      referringUser: 'FriendOfMine'
    }

    // Mock fetching the referring user.
    jest.mock('../getUserByUsername', () => {
      return () => null
    })

    await createUser(userContext, userToCreate.id,
      userToCreate.username, userToCreate.email, referralData)

    const expectedCreateItem = addTimestampFieldsToItem(userToCreate)
    expect(createMethod)
      .toHaveBeenCalledWith(userContext, expectedCreateItem)
    expect(logReferralData).not.toHaveBeenCalled()
    expect(rewardReferringUser).not.toHaveBeenCalled()
  })

  it('calls the database as expected', async () => {
    const UserModel = require('../UserModel').default
    const createUser = require('../createUser').default

    const userToCreate = clone(userInfo)
    const referralData = null
    const dbQueryMock = setMockDBResponse(
      DatabaseOperation.CREATE,
      {
        Attributes: {}
      }
    )
    const expectedUser = addTimestampFieldsToItem(new UserModel(userToCreate))
    const expectedParams = {
      Item: expectedUser,
      TableName: UserModel.tableName
    }
    const createdItem = await createUser(userContext, userToCreate.id,
      userToCreate.username, userToCreate.email, referralData)
    const dbParams = dbQueryMock.mock.calls[0][0]
    expect(dbParams).toEqual(expectedParams)
    expect(createdItem).toEqual(expectedUser)
  })
})

@@ -53,16 +53,265 @@
 /lang'%0A%0A
+import UserModel from '../UserModel'%0Aimport createUser from '../createUser'%0Aimport %7B logReferralData %7D from '../../referrals/referralData'%0Aimport getUserByUsername from '../getUserByUsername'%0Aimport rewardReferringUser from '../rewardReferringUser'%0A
 import %7B
@@ -311,16 +311,16 @@
 mport %7B%0A
-
   addTim
@@ -441,16 +441,51 @@
 utils'%0A%0A
+jest.mock('../../databaseClient')%0A%0A
 jest.moc
@@ -593,43 +593,8 @@
 ')%0A%0A
-jest.mock('../../databaseClient')%0A%0A
 cons
@@ -840,19 +840,20 @@
 est.
-resetModule
+clearAllMock
 s()%0A
@@ -952,277 +952,8 @@
 %3E %7B%0A
-    const UserModel = require('../UserModel').default%0A    const createUser = require('../createUser').default%0A    const logReferralData = require('../../referrals/referralData').logReferralData%0A    const rewardReferringUser = require('../rewardReferringUser').default%0A%0A
     
@@ -1532,277 +1532,8 @@
 %3E %7B%0A
-    const UserModel = require('../UserModel').default%0A    const createUser = require('../createUser').default%0A    const logReferralData = require('../../referrals/referralData').logReferralData%0A    const rewardReferringUser = require('../rewardReferringUser').default%0A%0A
     
@@ -1804,38 +1804,24 @@
 70fd4e'%0A    
-jest.mock('../
 getUserByUse
@@ -1817,35 +1817,56 @@
 etUserByUsername
-', 
+.mockImplementationOnce(
 () =%3E %7B%0A      re
@@ -1874,15 +1874,8 @@
 urn 
-() =%3E (
 %7B%0A  
@@ -1888,54 +1888,31 @@
 id: 
-'ppooiiuu-151a-4a9a-9289-06906670fd4e'
+referringUserId
 %0A      %7D
 )%0A  
@@ -1907,17 +1907,16 @@
 %0A      %7D
-)
 %0A    %7D)%0A
@@ -2427,277 +2427,8 @@
 %3E %7B%0A
-    const UserModel = require('../UserModel').default%0A    const createUser = require('../createUser').default%0A    const logReferralData = require('../../referrals/referralData').logReferralData%0A    const rewardReferringUser = require('../rewardReferringUser').default%0A%0A
     
@@ -2636,30 +2636,16 @@
 er.%0A    
-jest.mock('../
 getUserB
@@ -2653,19 +2653,40 @@
 Username
-', 
+.mockImplementationOnce(
 () =%3E %7B%0A
@@ -2697,22 +2697,16 @@
   return
- () =%3E
  null%0A  
@@ -3090,24 +3090,24 @@
 led()%0A  %7D)%0A%0A
+
   it('calls 
@@ -3151,119 +3151,8 @@
 %3E %7B%0A
-    const UserModel = require('../UserModel').default%0A    const createUser = require('../createUser').default%0A%0A
     

Clean up createUser tests.