Skip to content

Commit

Permalink
Merge pull request #18 from Rue-pro/refactor-remove-react-func-from-s…
Browse files Browse the repository at this point in the history
…tore

Refactor remove react func from store
  • Loading branch information
Rue-pro authored Apr 8, 2024
2 parents 5675461 + 6fc743b commit 1d10add
Show file tree
Hide file tree
Showing 16 changed files with 258 additions and 254 deletions.
51 changes: 26 additions & 25 deletions src/entities/dictionary/model/__tests__/store.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { allTasks, cleanStores, keepMount } from 'nanostores'
import { afterEach, describe, expect, test, vi } from 'vitest'

import { $errors } from '@entities/error/model/store'

import { chromeMockClearListeners } from '@shared/browser/__mocks__/chrome'
import { Result } from '@shared/libs/operationResult'
import { getErrorToastMock } from '@shared/ui/Toast/helpers/__mock__/getErrorToast'
import { addToastMock } from '@shared/ui/Toast/model/__mock__/store'

import { waitFor } from '@tests/testUtils'

Expand All @@ -21,6 +22,8 @@ describe('dictionary store', () => {
await chrome.storage.local.clear()
cleanStores($dictionaries)
$dictionaries.set(DICTIONARIES)
$errors.set([])
chromeMockClearListeners()
vi.clearAllMocks()
})

Expand All @@ -36,10 +39,10 @@ describe('dictionary store', () => {
await allTasks()

expect($dictionaries.get()).toEqual(newDictionaries)
expect(getErrorToastMock).toBeCalledTimes(0)
expect($errors.get().length).toEqual(0)
})

test('should set empty array and show toast with error when DictionaryStorage returns error', async () => {
test('should set empty array and set error when can not get data from DictionaryStorage', async () => {
vi.spyOn(DictionaryStorage, 'get').mockResolvedValueOnce(
Result.Error(error),
)
Expand All @@ -48,54 +51,55 @@ describe('dictionary store', () => {
await allTasks()

expect($dictionaries.get()).toEqual(DICTIONARIES)
expect(getErrorToastMock).toBeCalledWith(error)
expect($errors.get().length).toEqual(1)
})
})

describe('selectVariant', () => {
const dictionaryId = 'en_CambridgeDictionary'

test('should set selected variants to DictionaryStorage and show operation success information', async () => {
test('should set selected variants to DictionaryStorage and return operation success information', async () => {
keepMount($dictionaries)
await allTasks()

await waitFor(async () => {
await selectVariant('en', dictionaryId, 'us')
const result = await selectVariant('en', dictionaryId, 'us')

const call = addToastMock.mock.calls[0]
expect(call[0].type).toBe('success')
expect(call[0].title).toBeDefined()
expect(getErrorToastMock).toBeCalledTimes(0)
expect(result.data).toBeDefined()
expect(result.error).toBeNull()

const dictionary = $dictionaries
.get()
.en.dictionaries.find((dictionary) => {
dictionary.id === dictionaryId
})
.en.dictionaries.find((dictionary) => dictionary.id === dictionaryId)

if (dictionary && 'variants' in dictionary) {
expect(dictionary.activeVariant).toBe('us')
} else {
throw Error(
`Dictionary with id ${dictionaryId} and variants option not found`,
)
}
})
})

test('should show error if can not set to DictionaryStorage and keep previous variant', async () => {
test('should return error if can not set to DictionaryStorage and keep previous variant', async () => {
vi.spyOn(DictionaryStorage, 'set').mockResolvedValue(Result.Error(error))

keepMount($dictionaries)
await allTasks()

await waitFor(async () => {
await selectVariant('en', dictionaryId, 'us')
const result = await selectVariant('en', dictionaryId, 'us')

expect(getErrorToastMock).toBeCalledWith(error)
expect(result.data).toBeNull()
expect(result.error).toEqual(error)

const dictionary = $dictionaries
.get()
.en.dictionaries.find((dictionary) => dictionary.id === dictionaryId)

if (dictionary && 'variants' in dictionary) {
expect(dictionary.activeVariant).toEqual('uk')
expect(dictionary?.activeVariant).toEqual('uk')
} else {
throw Error(
`Dictionary with id ${dictionaryId} and variants option not found`,
Expand All @@ -104,18 +108,15 @@ describe('dictionary store', () => {
})
})

test('should show error if dictionary not found', async () => {
test('should return error if dictionary not found', async () => {
keepMount($dictionaries)
await allTasks()

await waitFor(async () => {
await selectVariant('en', 'NOT_EXISTING_ID', 'us')
const result = await selectVariant('en', 'NOT_EXISTING_ID', 'us')

const call = getErrorToastMock.mock.calls[0]
expect(call[0].type).toBe(
'ERROR_CAN_NOT_FIND_DICTIONARY_TO_SELECT_VARIANT',
)
expect(call[0].error).toBeDefined()
expect(result.data).toBeNull()
expect(result.error).toBeDefined()
})
})
})
Expand Down
11 changes: 3 additions & 8 deletions src/entities/dictionary/model/dictionaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,14 @@ export const DICTIONARIES: TDictionaries = {
],
activeVariant: 'uk',
},
{
id: 'en_GoogleTranslate',
name: 'Google Translate',
url: 'https://translate.google.com/',
},
],
},
jp: {
ja: {
label: 'Japanese',
value: 'jp',
value: 'ja',
dictionaries: [
{
id: 'jp_Jisho',
id: 'ja_Jisho',
name: 'Jisho',
url: 'https://jisho.org/',
},
Expand Down
52 changes: 25 additions & 27 deletions src/entities/dictionary/model/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import { TLanguageCode } from '@entities/language'
import { getStorage } from '@entities/storage'

import { browser } from '@shared/browser'
import { Result } from '@shared/libs/operationResult'
import { addToast, getErrorToast } from '@shared/ui/Toast'
import { Result, TResult } from '@shared/libs/operationResult'

import { DICTIONARIES } from './dictionaries'
import { TDictionaries } from './types'
Expand All @@ -22,19 +21,23 @@ export const $dictionaries = atom<StorageValue>(DICTIONARIES)
onMount($dictionaries, () => {
task(async () => {
const getResult = await DictionaryStorage.get()
if (getResult.data) {
$dictionaries.set(getResult.data)
} else {
addToast(getErrorToast(getResult.error))
}
getResult.data && $dictionaries.set(getResult.data)
})

const listener = DictionaryStorage.onChanged.addListener((changes) => {
changes.data && $dictionaries.set(changes.data.newValue)
})

return () => {
DictionaryStorage.onChanged.removeListener(listener)
}
})

export const selectVariant = async (
languageCode: TLanguageCode,
dictionaryId: string,
variant: string,
) => {
): Promise<TResult> => {
const dictionaries = $dictionaries.get()

const dictionary = dictionaries[languageCode].dictionaries.find(
Expand All @@ -57,25 +60,20 @@ export const selectVariant = async (
),
},
}

const setResult = await DictionaryStorage.set(newDictionaries)
if (setResult.data) {
$dictionaries.set(newDictionaries)
addToast({
type: 'success',
title: browser.i18n.getMessage('SELECT_DICTIONARY_VARIANT_SAVED'),
})
} else {
addToast(getErrorToast(setResult.error))
}
} else {
const resultError = Result.Error({
type: 'ERROR_CAN_NOT_FIND_DICTIONARY_TO_SELECT_VARIANT',
error: new Error(
`Dictionary with id ${dictionaryId} and variants option not found, available dictionaries: /n ${JSON.stringify(dictionaries)}`,
),
})
if (resultError.error) {
addToast(getErrorToast(resultError.error))
}

return setResult.data
? Result.Success(
browser.i18n.getMessage('SELECT_DICTIONARY_VARIANT_SAVED'),
)
: setResult
}

return Result.Error({
type: 'ERROR_CAN_NOT_FIND_DICTIONARY_TO_SELECT_VARIANT',
error: new Error(
`Dictionary with id ${dictionaryId} and variants option not found, available dictionaries: /n ${JSON.stringify(dictionaries)}`,
),
})
}
16 changes: 4 additions & 12 deletions src/entities/language/model/__tests__/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import { allTasks, cleanStores, keepMount } from 'nanostores'
import { afterEach, describe, expect, test, vi } from 'vitest'

import { Result } from '@shared/libs/operationResult'
import { getErrorToastMock } from '@shared/ui/Toast/helpers/__mock__/getErrorToast'
import { addToastMock } from '@shared/ui/Toast/model/__mock__/store'

import { waitFor } from '@tests/testUtils'

Expand Down Expand Up @@ -31,7 +29,6 @@ describe('languages store', () => {
await allTasks()

expect($languages.get()).toEqual([language])
expect(getErrorToastMock).toBeCalledTimes(0)
})

test('should set empty array and show toast with error when LanguagesStorage returns error', async () => {
Expand All @@ -43,7 +40,6 @@ describe('languages store', () => {
await allTasks()

expect($languages.get()).toEqual([])
expect(getErrorToastMock).toBeCalledWith(error)
})
})

Expand All @@ -55,11 +51,8 @@ describe('languages store', () => {
await allTasks()

waitFor(async () => {
select([])

const call = addToastMock.mock.calls[0]
expect(call[0].type).toBe('success')
expect(call[0].title).toBeDefined()
const result = await select([])
expect(result.error).toBeDefined()
})
})

Expand All @@ -70,9 +63,8 @@ describe('languages store', () => {
await allTasks()

waitFor(async () => {
select([])

expect(getErrorToastMock).toBeCalledWith(error)
const result = await select([])
expect(result.error).toBeDefined()
})
})
})
Expand Down
5 changes: 3 additions & 2 deletions src/entities/language/model/languages.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { ILanguage } from '.'

export const LANGUAGE_CODES = ['en', 'jp', 'pt', 'ko'] as const
export const LANGUAGE_CODES = ['en', 'ja', 'pt', 'ko', 'other'] as const

export const LANGUAGES: ILanguage[] = [
{ label: 'English', value: 'en' },
{ label: 'Japanese', value: 'jp' },
{ label: 'Japanese', value: 'ja' },
{ label: 'Portuguese', value: 'pt' },
{ label: 'Korean', value: 'ko' },
{ label: 'Other', value: 'other' },
]
33 changes: 17 additions & 16 deletions src/entities/language/model/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ILanguage, TLanguageCode } from '@entities/language'
import { getStorage } from '@entities/storage'

import { browser } from '@shared/browser'
import { addToast, getErrorToast } from '@shared/ui/Toast'
import { Result, TResult } from '@shared/libs/operationResult'

import { LANGUAGES } from './languages'

Expand All @@ -17,27 +17,28 @@ export const $languages = atom<StorageValue>(LANGUAGES)
onMount($languages, () => {
task(async () => {
const getResult = await LanguageStorage.get()
if (getResult.data) {
$languages.set(getResult.data)
} else {
addToast(getErrorToast(getResult.error))
}
getResult.data && $languages.set(getResult.data)
})

const listener = LanguageStorage.onChanged.addListener((changes) => {
changes.data && $languages.set(changes.data.newValue)
})

return () => {
LanguageStorage.onChanged.removeListener(listener)
}
})

export const select = async (languageCodes: TLanguageCode[]) => {
export const select = async (
languageCodes: TLanguageCode[],
): Promise<TResult> => {
const filteredLanguages = LANGUAGES.filter((language) =>
languageCodes.includes(language.value),
)

const setResult = await LanguageStorage.set(filteredLanguages)
if (setResult.data) {
$languages.set(filteredLanguages)
addToast({
type: 'success',
title: browser.i18n.getMessage('SELECTED_LANGUAGES_SAVED'),
})
} else {
addToast(getErrorToast(setResult.error))
}

return setResult.data
? Result.Success(browser.i18n.getMessage('SELECTED_LANGUAGES_SAVED'))
: setResult
}
Loading

0 comments on commit 1d10add

Please sign in to comment.