/* eslint redux-saga/no-unhandled-errors: 'off' */

import Chance from 'chance'
import * as R from 'ramda'
import {call, put, select} from 'redux-saga/effects'

import optionsFixture from '../../../../../common/__fixtures__/options.json'
import * as bookmarkCreators from '../../actions'
import bookmarkTrees from '../__fixtures__/bookmarkTrees'
import {getBookmarkTrees} from '../utils/getters'
import {getRestTreeIds, refreshBookmarkTrees} from './refreshBookmarkTrees'

const chance = Chance('refreshBookmarkTrees')

const getRestTreeIdsResult = [
  '5242',
  '7721',
  '9188',
  '2790',
  '3715',
  '9382',
  '8134',
  '8333',
  '7925'
]

describe('getRestTreeIds', () => {
  test('get all tree ids except first tree', () => {
    expect(getRestTreeIds(bookmarkTrees)).toEqual(getRestTreeIdsResult)
  })
  test('allow empty array', () => {
import Chance from 'chance'

import * as CST from '../../../constants'
import bookmarkNodes from '../saga/__fixtures__/bookmarkNodes'
import bookmarkTrees from '../saga/__fixtures__/bookmarkTrees'
import * as converters from './converters'

const chance = Chance('converters')

const templateBookmarkInfo = bookmarkTrees[0].children[0]

describe('getIconUrl', () => {
  test('return bookmark url if it is bookmark', () => {
    const url = chance.url()
    expect(
      converters.getIconUrl({
        ...templateBookmarkInfo,
        type: CST.BOOKMARK_TYPES.BOOKMARK,
        url
      })
    ).toBe(`chrome://favicon/${url}`)
  })
  test('return folder icon if it is folder', () => {
    expect(
      converters.getIconUrl({
        ...templateBookmarkInfo,
        type: CST.BOOKMARK_TYPES.FOLDER
      })
    ).toBe('test-file-stub')
  })
  test('return empty string if it is neither bookmark nor folder', () => {
/* eslint redux-saga/no-unhandled-errors: 'off' */

import Chance from 'chance'
import {call, put} from 'redux-saga/effects'
import {getType} from 'typesafe-actions'

import {queryTabs} from '../../../../../common/utils'
import * as bookmarkCreators from '../../actions'
import {addCurrentPage} from './addCurrentPage'

const chance = Chance('addCurrentPage')

const currentTabs = [
  {
    title: '  title  ',
    url: '  https://google.com/  '
  },
  {
    title: chance.word(),
    url: chance.url()
  }
]

describe('addCurrentPage', () => {
  test('should successfully add current tab as bookmark', () => {
    const index = chance.integer()
    const parentId = String(chance.integer())

    const generator = addCurrentPage({
      type: getType(bookmarkCreators.addCurrentPage),
      payload: {parentId, index}
/* eslint redux-saga/no-unhandled-errors: 'off' */

import Chance from 'chance'
import {put} from 'redux-saga/effects'
import {getType} from 'typesafe-actions'

import * as CST from '../../../../constants'
import * as bookmarkCreators from '../../actions'
import {addSeparator} from './addSeparator'

jest.mock('nanoid', () => () => 'mocked-id')

const chance = Chance('addSeparator')

describe('addSeparator', () => {
  test('should successfully add separator', () => {
    const index = chance.integer()
    const parentId = String(chance.integer())

    const generator = addSeparator({
      type: getType(bookmarkCreators.addSeparator),
      payload: {parentId, index}
    })

    expect(generator.next().value).toEqual(
      put(
        bookmarkCreators.createBookmark(
          parentId,
          index,
          '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -',
          CST.SEPARATE_THIS_URL + '#mocked-id'
/* eslint redux-saga/no-unhandled-errors: 'off' */

import {cloneableGenerator} from '@redux-saga/testing-utils'
import Chance from 'chance'
import {call} from 'redux-saga/effects'
import {getType} from 'typesafe-actions'

import {removeBookmark, removeBookmarkTree} from '../../../../../common/utils'
import * as CST from '../../../../constants'
import * as bookmarkCreators from '../../actions'
import bookmarkTrees from '../__fixtures__/bookmarkTrees'
import {getBookmarkInfo} from '../utils/getters'
import {deleteBookmark} from './deleteBookmark'

const chance = Chance('deleteBookmark')

const createGenerator = (id: string) => {
  return cloneableGenerator(deleteBookmark)({
    type: getType(bookmarkCreators.deleteBookmark),
    payload: {id}
  })
}

describe('deleteBookmark', () => {
  const id = String(chance.integer())
  let generator = createGenerator(id)

  beforeAll(() => {
    generator = createGenerator(id)

    expect(generator.next().value).toEqual(call(getBookmarkInfo, id))
import Chance from 'chance'
import * as R from 'ramda'

import * as CST from '../../../../constants'

const chance = Chance('bookmarkTrees')

const generateType = () =>
  chance.pickone([
    CST.BOOKMARK_TYPES.BOOKMARK,
    CST.BOOKMARK_TYPES.FOLDER,
    CST.BOOKMARK_TYPES.SEPARATOR
  ])

const generateBookmarkInfo = (type?: CST.BOOKMARK_TYPES) => ({
  id: String(chance.integer({min: 1000, max: 9999})),
  parentId: String(chance.integer({min: 1000, max: 9999})),
  title: chance.word(),
  url: chance.url(),
  iconUrl: chance.url(),
  storageIndex: chance.integer({min: -1, max: 9999}),
  type: type || generateType(),
  isRoot: chance.bool(),
  isSimulated: false,
  isUnmodifiable: chance.bool()
})

export const generateBookmarkTree = () => ({
  children: R.times(() => generateBookmarkInfo(), 20),
  parent: generateBookmarkInfo(CST.BOOKMARK_TYPES.FOLDER)
})
import Chance from 'chance'
import * as R from 'ramda'

const chance = Chance('bookmarkNodes')

const generateBookmarkNode = (): browser.bookmarks.BookmarkTreeNode => ({
  id: String(chance.integer({min: 1000, max: 9999})),
  ...(chance.bool() ? {parentId: String(chance.integer({min: 1000, max: 9999}))} : null),
  ...(chance.bool() ? {index: chance.integer({min: 1000, max: 9999})} : null),
  ...(chance.bool() ? {url: chance.url()} : null),
  title: chance.word(),
  ...(chance.bool() ? {dateAdded: chance.integer({min: 1500000000000, max: 2000000000000})} : null),
  ...(chance.bool() ?
    {
      dateGroupModified: chance.integer({min: 1500000000000, max: 2000000000000})
    } :
    null),
  ...(chance.bool() ? {unmodifiable: 'managed'} : null)
})

export default R.times(generateBookmarkNode, 100)
import Chance from 'chance'
import * as R from 'ramda'
import {call, put, select} from 'redux-saga/effects'
import {getType} from 'typesafe-actions'

import optionsFixture from '../../../../../common/__fixtures__/options.json'
import {OPTIONS} from '../../../../constants'
import * as bookmarkCreators from '../../actions'
import bookmarkTrees from '../__fixtures__/bookmarkTrees'
import searchResult from '../__fixtures__/searchResult'
import searchTitleOnlyResult from '../__fixtures__/searchTitleOnlyResult'
import {searchBookmarks} from '../utils/getters'
import {getSearchResult, searchKeywordMatcher} from './getSearchResult'

const chance = Chance('getSearchResult')

describe('searchKeywordMatcher', () => {
  test('return true if all keywords is matched', () => {
    const searchKeyword = 'a b c'

    expect(searchKeywordMatcher(searchKeyword, 'abc')).toBe(true)
    expect(searchKeywordMatcher(searchKeyword, 'cab')).toBe(true)
    expect(searchKeywordMatcher(searchKeyword, 'cabdefg')).toBe(true)
  })
  test('return false if one of the keywords is not matched', () => {
    const searchKeyword = 'a b c'

    expect(searchKeywordMatcher(searchKeyword, 'ca')).toBe(false)
    expect(searchKeywordMatcher(searchKeyword, 'z')).toBe(false)
    expect(searchKeywordMatcher(searchKeyword, '')).toBe(false)
import * as R from 'ramda'
import {all, call} from 'redux-saga/effects'

import optionsFixture from '../../../../../common/__fixtures__/options.json'
import {
  getBookmarkChildNodes,
  getBookmarkNodes,
  searchBookmarkNodes
} from '../../../../../common/utils'
import * as CST from '../../../../constants'
import {BookmarkTree} from '../../../../types'
import bookmarkNodes from '../__fixtures__/bookmarkNodes'
import bookmarkTrees from '../__fixtures__/bookmarkTrees'
import * as getters from './getters'

const chance = Chance('getters')

describe('getBookmarkInfo', () => {
  test('should get the first bookmark node by id and convert it to bookmarkInfo', () => {
    const generator = getters.getBookmarkInfo(bookmarkNodes[0].id)

    expect(generator.next().value).toEqual(call(getBookmarkNodes, bookmarkNodes[0].id))

    expect(generator.next(bookmarkNodes).value).toMatchSnapshot()

    expect(generator.next().done).toBe(true)
  })
})

describe('getBookmarkChildren', () => {
  test('should get all its children by id and convert all children to bookmarkInfo', () => {