0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DrillDown Pt.5

Last updated at Posted at 2022-02-12

Continuation from pt.4

Implementation

4. test DrillDownSearch

Create files

touch __tests__/pages/DrillDownSearch.spec.js
mkdir -p __tests__/components
touch __tests__/components/Dialog.spec.js
touch __tests__/components/DrillDown.spec.js

Describe DrillDownSearch page

vim __tests__/pages/DrillDownSearch.spec.js

// __tests__/pages/DrillDownSearch.spec.js
import { mount } from  '@vue/test-utils'
import Vue from 'vue'
import Vuetify from 'vuetify'
import DrillDownSearch from '../../pages/DrillDownSearch.vue'

Vue.use(Vuetify)

// cf. https://github.com/vuejs/vue-test-utils/issues/974#issuecomment-423721358
// [Vue warn]: Error in mounted hook: "ReferenceError: requestAnimationFrame is not defined"
global.requestAnimationFrame = (cb) => cb()

// This is temporary solution for remove warn below
// [Vue warn]: Error in callback for watcher "isActive": "ReferenceError: cancelAnimationFrame is not defined"
global.cancelAnimationFrame = function() {
  setTimeout(function() {}, 0)
}

// This is temporary solution for remove warn below
// [Vue warn]: Error in directive click-outside inserted hook: "ReferenceError: ShadowRoot is not defined"
global.ShadowRoot = (cb) => cb()

// cf. https://github.com/vuejs/vue/issues/9698#issuecomment-473258879
// Attempted to log "[Vue warn]: Error in callback for watcher "listIndex": "ReferenceError: performance is not defined"
// eslint-disable-next-line no-undef
global.performance = window.performance;

describe('DrillDownSearch page', () => {
  const app = document.createElement('div')
  app.setAttribute('data-app', true)
  document.body.appendChild(app)

  let vuetify
  let wrapper

  beforeEach(() => {
    vuetify = new Vuetify
    wrapper = mount(DrillDownSearch, {
      vuetify,
      stubs: ['DrillDown']
    })
  })

  it('test', () => {
    expect(1).toBe(1)
  })
})
It should use dialog when use drilldown
vim __tests__/pages/DrillDownSearch.spec.js

// __tests__/pages/DrillDownSearch.spec.js
// ...
describe('DrillDownSearch page', () => {
  // ...
  it('should use dialog when use drilldown', async () => {
    const buttonElms = wrapper.findAll('.v-btn')
    buttonElms.at(0).trigger('click')
    await wrapper.vm.$nextTick()
    expect(wrapper.vm.isDialogOpened).toBe(true)
  })
})
It can access DrillDown data when dialog have been closed
vim __tests__/pages/DrillDownSearch.spec.js

// __tests__/pages/DrillDownSearch.spec.js
// ...
describe('DrillDownSearch page', () => {
  // ...
  it('can access DrillDown data when dialog have been closed', async () => {
    const buttonElms = wrapper.findAll('.v-btn')
    buttonElms.at(0).trigger('click')
    await wrapper.vm.$nextTick()
    wrapper.vm.$refs.confirm.agree()
    await wrapper.vm.$nextTick()
    expect(wrapper.vm.isResoleved).toBe(true)
  })
})

Describe Dialog component

vim __tests__/components/Dialog.spec.js

// __tests__/components/Dialog.spec.js
import { mount } from  '@vue/test-utils'
import Vue from 'vue'
import Vuetify from 'vuetify'
import Dialog from '../../components/Dialog.vue'

Vue.use(Vuetify)

// cf. https://github.com/vuejs/vue-test-utils/issues/974#issuecomment-423721358
// [Vue warn]: Error in mounted hook: "ReferenceError: requestAnimationFrame is not defined"
global.requestAnimationFrame = (cb) => cb()

// This is temporary solution for remove warn below
// [Vue warn]: Error in callback for watcher "isActive": "ReferenceError: cancelAnimationFrame is not defined"
global.cancelAnimationFrame = function() {
  setTimeout(function() {}, 0)
}

// This is temporary solution for remove warn below
// [Vue warn]: Error in directive click-outside inserted hook: "ReferenceError: ShadowRoot is not defined"
global.ShadowRoot = (cb) => cb()

// cf. https://github.com/vuejs/vue/issues/9698#issuecomment-473258879
// Attempted to log "[Vue warn]: Error in callback for watcher "listIndex": "ReferenceError: performance is not defined"
// eslint-disable-next-line no-undef
global.performance = window.performance;

describe('Dialog component', () => {
  const app = document.createElement('div')
  app.setAttribute('data-app', true)
  document.body.appendChild(app)

  let wrapper
  let vuetify

  beforeEach(() => {
    vuetify = new Vuetify
    wrapper = mount(Dialog, {
      vuetify
    })
    jest.spyOn(wrapper.vm, 'agree')
    jest.spyOn(wrapper.vm, 'cancel')
  })

  it('test', () => {
    expect(1).toBe(1)
  })
})
It should return Promise when open itself (pending)
vim __tests__/components/Dialog.spec.js

// __tests__/components/Dialog.spec.js
// ...
describe('Dialog component', () => {
  it('should return Promise when open itself (pending)', async () => {
    const ret = wrapper.vm.open()
    await wrapper.vm.$nextTick()
    expect(ret instanceof Promise).toBe(true)
  })
})
It should resolve/reject Promise when close itself (notification)
vim __tests__/components/Dialog.spec.js

// __tests__/components/Dialog.spec.js
// ...
describe('Dialog component', () => {
  it('should resolve/reject Promise when close itself (notification)', async () => {
    const ret = wrapper.vm.open()
    await wrapper.vm.$nextTick()
    const buttonElms = wrapper.findAll('.v-btn')
    buttonElms.at(0).trigger('click')
    expect(wrapper.vm.cancel).toHaveBeenCalled()
    buttonElms.at(1).trigger('click')
    expect(wrapper.vm.agree).toHaveBeenCalled()
  })
})

Describe DrillDown component

vim __tests__/components/DrillDown.spec.js

// __tests__/components/DrillDown.spec.js
import { mount } from  '@vue/test-utils'
import Vue from 'vue'
import Vuetify from 'vuetify'
import Vuex from 'vuex'
import axios from 'axios'
import DrillDown from '../../components/DrillDown.vue'

Vue.use(Vuetify)
Vue.use(Vuex)

jest.mock('axios', () => ({
  $get: jest.fn((path, { params }) => {
    const res = makeResDataBy(params)
    return Promise.resolve(res)
  })
}))

const makeResDataBy = (params) => {
  const dummy = require('../../__mock__/api/drillDown/dummy.json')
  const res = {
    option2: null,
    option3: null
  }  
  const reqKeys = Object.keys(params)
  const resKeys = Object.keys(res)
  const reqLength = Object.keys(params).length
  const reqKey = reqKeys[reqLength - 1]
  const resKey = resKeys[reqLength - 1]
  const reqValue = params[reqKey]
  res[resKey] = dummy[reqValue]

  return res
}

const state = {
  drillDown: {
    option2: null,
    option3: null
  }
}


const actions = {
  'drillDown/fetch': jest.fn(async ({ commit }, params) => {
    const path = `/drillDown`
    axios.$get(path, {params: params})
      .then(res => {
        commit('SET', res)
      })
  })
}

const mutations = {
  SET(state, obj) {
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
      if (obj[keys[i]]) {
        state.drillDown[keys[i]] = obj[keys[i]]
        break
      }
    }
  }
}

// cf. https://github.com/vuejs/vue-test-utils/issues/974#issuecomment-423721358
// [Vue warn]: Error in mounted hook: "ReferenceError: requestAnimationFrame is not defined"
global.requestAnimationFrame = (cb) => cb()

// This is temporary solution for remove warn below
// [Vue warn]: Error in directive click-outside inserted hook: "ReferenceError: ShadowRoot is not defined"
global.ShadowRoot = (cb) => cb()

// cf. https://github.com/vuejs/vue/issues/9698#issuecomment-473258879
// Attempted to log "[Vue warn]: Error in callback for watcher "listIndex": "ReferenceError: performance is not defined"
// eslint-disable-next-line no-undef
global.performance = window.performance;

describe('DrillDown component', () => {
  // NOTE: this code cause transition-stub do not function
  // const app = document.createElement('div')
  // app.setAttribute('data-app', true)
  // document.body.appendChild(app)

  let wrapper
  let vuetify
  let store

  beforeEach(() => {
    axios.$get.mockClear();
    vuetify = new Vuetify()
    store = new Vuex.Store({
      state,
      actions,
      mutations
    })
    wrapper = mount(DrillDown, {
      vuetify,
      store,
      propsData: {
        firstItems: [1, 2, 3],
        initialItem: {
          option1: '1',
          option2: '',
          option3: ''
        },
        path: 'drillDown/fetch'
      }
    })
  })

  it('test', () => {
    expect(1).toBe(1)
  })
})
It have multiple slot
vim __tests__/components/DrillDown.spec.js

// __tests__/components/DrillDown.spec.js
// ...
describe('DrillDown', () => {
  // ...
  it('have multiple slot', () => {
    const elm = wrapper.findAll('.v-input__slot')
    expect(elm.length > 1).toBe(true)
  })
})
It get options and initial value from parent Class
vim __tests__/components/DrillDown.spec.js

// __tests__/components/DrillDown.spec.js
// ...
describe('DrillDown', () => {
  // ...
  it('get options and initial value from parent Class', () => {
    const list = []
    const inputElms = wrapper.findAll('input')
    for (let i = 0; i < inputElms.length; i++) {
      if (inputElms.at(i).attributes().type !== 'hidden') continue
      if (inputElms.at(i).attributes().value) {
        list.push(inputElms.at(i).attributes().value)
        continue
      }
      list.push('')
    }
    const initialItem = wrapper.props().initialItem
    Object.keys(initialItem).forEach((item, index) => {
      expect(initialItem[item]).toBe(list[index])
    })
  })
})
It is selected in order
vim __tests__/components/DrillDown.spec.js

// __tests__/components/DrillDown.spec.js
// ...
describe('DrillDown', () => {
  // ...
  it('is selected in order', () => {
    const selections = wrapper.findAll('.v-select__selections')
    const initialItem = wrapper.props().initialItem
    const optionKeys = Object.keys(initialItem)
    let nextIndex = 0
    for (let i = 0; i < optionKeys.length; i++) {
      if (initialItem[optionKeys[i]] === '') break
      nextIndex++
    }
    const disabled = selections.at(nextIndex + 1).find('input').attributes().disabled
    expect(disabled).toBe('disabled')
  })
})
It get the next item from api each time one item is selected
vim __tests__/components/DrillDown.spec.js

// __tests__/components/DrillDown.spec.js
// ...
describe('DrillDown', () => {
  // ...
  it('get the next item from api each time one item is selected', async () => {
    const inputElms = wrapper.findAll('.v-input__slot')
    wrapper.vm.$nextTick(() => {
      expect(axios.$get).toHaveBeenCalledTimes(2)
    })

    inputElms.at(0).trigger('click')
    await wrapper.vm.$nextTick()
    const itemElms = wrapper.findAll('.v-list-item')
    itemElms.at(2).trigger('click')
    await wrapper.vm.$nextTick()
    wrapper.vm.$nextTick(() => {
      expect(axios.$get).toHaveBeenCalledTimes(3)
    })
  })
})
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?