mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
frontend unit tests
toasts component testing conditional import of angular setup-jest for vscode-jest support Update jest.config.js Create open-documents.service.spec.ts Add unit tests for all REST services settings service test Remove component from settings service test Create permissions.service.spec.ts upload documents service tests Update package.json Create toast.service.spec.ts Tasks service test Statistics widget component tests Update permissions.service.ts Create app.component.spec.ts settings component testing tasks component unit testing Management list component generic tests Some management component tests document notes component unit tests Create document-list.component.spec.ts Create save-view-config-dialog.component.spec.ts Create filter-editor.component.spec.ts small and large document cards unit testing Create bulk-editor.component.spec.ts document detail unit tests saving work on documentdetail component spec Create document-asn.component.spec.ts dashboard & widgets unit testing Fix ResizeObserver mock common component unit tests fix some merge errors Update app-frame.component.spec.ts Create page-header.component.spec.ts input component unit tests FilterableDropdownComponent unit testing and found minor errors update taskservice unit tests Edit dialogs unit tests Create date-dropdown.component.spec.ts Remove selectors from guard tests confirm dialog component tests app frame component test Miscellaneous component tests Update document-list-view.service.spec.ts directives unit tests Remove unused resizeobserver mock guard unit tests Update query-params.spec.ts try to fix flaky playwright filter rules utils & testing Interceptor unit tests Pipes unit testing Utils unit tests Update upload-documents.service.spec.ts consumer status service tests Update setup-jest.ts Create document-list-view.service.spec.ts Update app-routing.module.ts
This commit is contained in:
50
src-ui/src/app/utils/color.spec.ts
Normal file
50
src-ui/src/app/utils/color.spec.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
BRIGHTNESS,
|
||||
computeLuminance,
|
||||
estimateBrightnessForColor,
|
||||
hexToHsl,
|
||||
randomColor,
|
||||
rgbToHsl,
|
||||
} from './color'
|
||||
|
||||
describe('Color Utils', () => {
|
||||
it('should convert hex to hsl', () => {
|
||||
let hsl = hexToHsl('#0000FF')
|
||||
expect(hsl).toEqual({
|
||||
h: 0.6666666666666666,
|
||||
s: 1,
|
||||
l: 0.5,
|
||||
})
|
||||
})
|
||||
|
||||
it('should compute luminance', () => {
|
||||
let luminance = computeLuminance({ r: 0, g: 0, b: 0 })
|
||||
expect(luminance).toEqual(0)
|
||||
luminance = computeLuminance({ r: 255, g: 255, b: 255 })
|
||||
expect(luminance).toEqual(1)
|
||||
luminance = computeLuminance({ r: 128, g: 128, b: 128 })
|
||||
expect(luminance).toBeCloseTo(0.22)
|
||||
})
|
||||
|
||||
it('should estimate brightness', () => {
|
||||
let brightness = estimateBrightnessForColor('#FFFF00') // yellow
|
||||
expect(brightness).toEqual(BRIGHTNESS.LIGHT)
|
||||
brightness = estimateBrightnessForColor('#800000') // maroon
|
||||
expect(brightness).toEqual(BRIGHTNESS.DARK)
|
||||
})
|
||||
|
||||
it('should convert rgb to hsl', () => {
|
||||
let hsl = rgbToHsl(0, 255, 0)
|
||||
expect(hsl).toEqual([0.3333333333333333, 1, 0.5])
|
||||
hsl = rgbToHsl(255, 255, 0)
|
||||
expect(hsl).toEqual([0.16666666666666666, 1, 0.5])
|
||||
hsl = rgbToHsl(0, 0, 255)
|
||||
expect(hsl).toEqual([0.6666666666666666, 1, 0.5])
|
||||
hsl = rgbToHsl(128, 128, 128)
|
||||
expect(hsl).toEqual([0, 0, 0.5019607843137255])
|
||||
})
|
||||
|
||||
it('should return a random color', () => {
|
||||
expect(randomColor()).not.toBeNull()
|
||||
})
|
||||
})
|
48
src-ui/src/app/utils/filter-rules.spec.ts
Normal file
48
src-ui/src/app/utils/filter-rules.spec.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import { cloneFilterRules } from './filter-rules'
|
||||
import { FilterRule } from '../data/filter-rule'
|
||||
import {
|
||||
FILTER_FULLTEXT_QUERY,
|
||||
FILTER_HAS_TAGS_ALL,
|
||||
} from '../data/filter-rule-type'
|
||||
import { isFullTextFilterRule } from './filter-rules'
|
||||
import { filterRulesDiffer } from './filter-rules'
|
||||
|
||||
const filterRules: FilterRule[] = [
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: '9',
|
||||
},
|
||||
]
|
||||
|
||||
describe('FilterRules Utils', () => {
|
||||
it('should clone filter rules', () => {
|
||||
let rules = cloneFilterRules(filterRules)
|
||||
expect(rules).toEqual(filterRules)
|
||||
|
||||
rules = cloneFilterRules(null)
|
||||
expect(rules).toBeNull()
|
||||
})
|
||||
|
||||
it('should determine if filter rule is a full text rule', () => {
|
||||
const rules = [
|
||||
{
|
||||
rule_type: FILTER_FULLTEXT_QUERY,
|
||||
value: 'hello',
|
||||
},
|
||||
]
|
||||
expect(isFullTextFilterRule(rules)).toBeTruthy()
|
||||
expect(isFullTextFilterRule(filterRules)).toBeFalsy()
|
||||
})
|
||||
|
||||
it('should determine if filter rule sets differ', () => {
|
||||
const rules2 = [
|
||||
{
|
||||
rule_type: FILTER_FULLTEXT_QUERY,
|
||||
value: 'hello',
|
||||
},
|
||||
]
|
||||
expect(filterRulesDiffer(filterRules, [])).toBeTruthy()
|
||||
expect(filterRulesDiffer(filterRules, rules2)).toBeTruthy()
|
||||
expect(filterRulesDiffer(filterRules, filterRules)).toBeFalsy()
|
||||
})
|
||||
})
|
46
src-ui/src/app/utils/filter-rules.ts
Normal file
46
src-ui/src/app/utils/filter-rules.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { FilterRule } from '../data/filter-rule'
|
||||
import {
|
||||
FILTER_FULLTEXT_MORELIKE,
|
||||
FILTER_FULLTEXT_QUERY,
|
||||
} from '../data/filter-rule-type'
|
||||
|
||||
export function cloneFilterRules(filterRules: FilterRule[]): FilterRule[] {
|
||||
if (filterRules) {
|
||||
let newRules: FilterRule[] = []
|
||||
for (let rule of filterRules) {
|
||||
newRules.push({ rule_type: rule.rule_type, value: rule.value })
|
||||
}
|
||||
return newRules
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function isFullTextFilterRule(filterRules: FilterRule[]): boolean {
|
||||
return (
|
||||
filterRules.find(
|
||||
(r) =>
|
||||
r.rule_type == FILTER_FULLTEXT_QUERY ||
|
||||
r.rule_type == FILTER_FULLTEXT_MORELIKE
|
||||
) != null
|
||||
)
|
||||
}
|
||||
|
||||
export function filterRulesDiffer(
|
||||
filterRulesA: FilterRule[],
|
||||
filterRulesB: FilterRule[]
|
||||
): boolean {
|
||||
let differ = false
|
||||
if (filterRulesA.length != filterRulesB.length) {
|
||||
differ = true
|
||||
} else {
|
||||
differ = filterRulesA.some((rule) => {
|
||||
return (
|
||||
filterRulesB.find(
|
||||
(fri) => fri.rule_type == rule.rule_type && fri.value == rule.value
|
||||
) == undefined
|
||||
)
|
||||
})
|
||||
}
|
||||
return differ
|
||||
}
|
67
src-ui/src/app/utils/ngb-date-parser-formatter.spec.ts
Normal file
67
src-ui/src/app/utils/ngb-date-parser-formatter.spec.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { LocalizedDateParserFormatter } from './ngb-date-parser-formatter'
|
||||
import { SettingsService } from '../services/settings.service'
|
||||
import {
|
||||
HttpClientTestingModule,
|
||||
HttpTestingController,
|
||||
} from '@angular/common/http/testing'
|
||||
|
||||
describe('LocalizedDateParserFormatter', () => {
|
||||
let dateParserFormatter: LocalizedDateParserFormatter
|
||||
let settingsService: SettingsService
|
||||
let httpTestingController: HttpTestingController
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [LocalizedDateParserFormatter, SettingsService],
|
||||
imports: [HttpClientTestingModule],
|
||||
})
|
||||
|
||||
dateParserFormatter = TestBed.inject(LocalizedDateParserFormatter)
|
||||
settingsService = TestBed.inject(SettingsService)
|
||||
httpTestingController = TestBed.inject(HttpTestingController)
|
||||
})
|
||||
|
||||
it('should parse date to struct by locale', () => {
|
||||
let val = dateParserFormatter.parse('5/4/2023')
|
||||
expect(val).toEqual({ day: 4, month: 5, year: 2023 })
|
||||
val = dateParserFormatter.parse('5/4/23')
|
||||
expect(val.day).toEqual(4)
|
||||
expect(val.month).toEqual(5)
|
||||
expect(val.year).toEqual(2023)
|
||||
val = dateParserFormatter.parse('05042023')
|
||||
expect(val.day).toEqual(4)
|
||||
expect(val.month).toEqual(5)
|
||||
expect(val.year).toEqual(2023)
|
||||
val = dateParserFormatter.parse('12/13')
|
||||
expect(val.day).toEqual(13)
|
||||
expect(val.month).toEqual(12)
|
||||
expect(val.year).toEqual(new Date().getFullYear())
|
||||
|
||||
settingsService.setLanguage('de-de') // dd.mm.yyyy
|
||||
val = dateParserFormatter.parse('04.05.2023')
|
||||
expect(val).toEqual({ day: 4, month: 5, year: 2023 })
|
||||
val = dateParserFormatter.parse('04052023')
|
||||
expect(val).toEqual({ day: 4, month: 5, year: 2023 })
|
||||
|
||||
settingsService.setLanguage('tr-tr') // yyyy-mm-dd
|
||||
val = dateParserFormatter.parse('2023-05-04')
|
||||
expect(val).toEqual({ day: 4, month: 5, year: 2023 })
|
||||
val = dateParserFormatter.parse('20230504')
|
||||
expect(val).toEqual({ day: 4, month: 5, year: 2023 })
|
||||
})
|
||||
|
||||
it('should parse date struct to string by locale', () => {
|
||||
const dateStruct = {
|
||||
day: 4,
|
||||
month: 5,
|
||||
year: 2023,
|
||||
}
|
||||
let dateStr = dateParserFormatter.format(dateStruct)
|
||||
expect(dateStr).toEqual('05/04/2023')
|
||||
|
||||
settingsService.setLanguage('de-de') // dd.mm.yyyy
|
||||
dateStr = dateParserFormatter.format(dateStruct)
|
||||
expect(dateStr).toEqual('04.05.2023')
|
||||
})
|
||||
})
|
40
src-ui/src/app/utils/ngb-iso-date-adapter.spec.ts
Normal file
40
src-ui/src/app/utils/ngb-iso-date-adapter.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { TestBed } from '@angular/core/testing'
|
||||
import { ISODateAdapter } from './ngb-iso-date-adapter'
|
||||
|
||||
describe('ISODateAdapter', () => {
|
||||
let isoDateAdapter: ISODateAdapter
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [ISODateAdapter],
|
||||
})
|
||||
isoDateAdapter = TestBed.inject(ISODateAdapter)
|
||||
})
|
||||
|
||||
it('should parse ISO date to struct', () => {
|
||||
let val = isoDateAdapter.fromModel('2023-05-04')
|
||||
expect(val.day).toEqual(4)
|
||||
expect(val.month).toEqual(5)
|
||||
expect(val.year).toEqual(2023)
|
||||
|
||||
val = isoDateAdapter.fromModel(null)
|
||||
expect(val).toBeNull()
|
||||
|
||||
val = isoDateAdapter.fromModel('5/4/23')
|
||||
expect(val.day).toEqual(4)
|
||||
expect(val.month).toEqual(5)
|
||||
expect(val.year).toEqual(2023)
|
||||
})
|
||||
|
||||
it('should parse struct to ISO date', () => {
|
||||
let val = isoDateAdapter.toModel({
|
||||
day: 4,
|
||||
month: 5,
|
||||
year: 2023,
|
||||
})
|
||||
expect(val).toEqual('2023-05-04')
|
||||
|
||||
val = isoDateAdapter.toModel(null)
|
||||
expect(val).toBeNull()
|
||||
})
|
||||
})
|
196
src-ui/src/app/utils/query-params.spec.ts
Normal file
196
src-ui/src/app/utils/query-params.spec.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
import { convertToParamMap } from '@angular/router'
|
||||
import { FilterRule } from '../data/filter-rule'
|
||||
import {
|
||||
FILTER_CORRESPONDENT,
|
||||
FILTER_HAS_ANY_TAG,
|
||||
FILTER_HAS_TAGS_ALL,
|
||||
} from '../data/filter-rule-type'
|
||||
import { paramsToViewState } from './query-params'
|
||||
import { paramsFromViewState } from './query-params'
|
||||
import { queryParamsFromFilterRules } from './query-params'
|
||||
import { filterRulesFromQueryParams } from './query-params'
|
||||
|
||||
const tags__id__all = '9'
|
||||
const filterRules: FilterRule[] = [
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: tags__id__all,
|
||||
},
|
||||
]
|
||||
|
||||
describe('QueryParams Utils', () => {
|
||||
it('should convert view state to params', () => {
|
||||
let params = paramsFromViewState({
|
||||
sortField: 'added',
|
||||
sortReverse: true,
|
||||
currentPage: 2,
|
||||
filterRules,
|
||||
})
|
||||
expect(params).toEqual({
|
||||
sort: 'added',
|
||||
reverse: 1,
|
||||
page: 2,
|
||||
tags__id__all,
|
||||
})
|
||||
|
||||
params = paramsFromViewState({
|
||||
sortField: 'created',
|
||||
sortReverse: false,
|
||||
currentPage: NaN,
|
||||
filterRules: [],
|
||||
})
|
||||
expect(params).toEqual({
|
||||
sort: 'created',
|
||||
reverse: undefined,
|
||||
page: 1,
|
||||
})
|
||||
|
||||
params = paramsFromViewState(
|
||||
{
|
||||
sortField: 'created',
|
||||
sortReverse: false,
|
||||
currentPage: 1,
|
||||
filterRules: [],
|
||||
},
|
||||
true
|
||||
)
|
||||
expect(params).toEqual({
|
||||
page: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it('should convert params to view state', () => {
|
||||
const params = {
|
||||
sort: 'created',
|
||||
reverse: 1,
|
||||
page: 1,
|
||||
}
|
||||
const state = paramsToViewState(convertToParamMap(params))
|
||||
expect(state).toMatchObject({
|
||||
currentPage: 1,
|
||||
sortField: 'created',
|
||||
sortReverse: true,
|
||||
filterRules: [],
|
||||
})
|
||||
})
|
||||
|
||||
it('should convert params to filter rules', () => {
|
||||
let params = queryParamsFromFilterRules(filterRules)
|
||||
expect(params).toEqual({
|
||||
tags__id__all,
|
||||
})
|
||||
|
||||
params = queryParamsFromFilterRules([
|
||||
{
|
||||
rule_type: FILTER_CORRESPONDENT,
|
||||
value: null,
|
||||
},
|
||||
])
|
||||
expect(params).toEqual({
|
||||
correspondent__isnull: 1,
|
||||
})
|
||||
|
||||
params = queryParamsFromFilterRules([
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_TAG,
|
||||
value: 'true',
|
||||
},
|
||||
])
|
||||
expect(params).toEqual({
|
||||
is_tagged: 1,
|
||||
})
|
||||
|
||||
params = queryParamsFromFilterRules([
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_TAG,
|
||||
value: 'false',
|
||||
},
|
||||
])
|
||||
expect(params).toEqual({
|
||||
is_tagged: 0,
|
||||
})
|
||||
|
||||
params = queryParamsFromFilterRules([
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: tags__id__all,
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: '14',
|
||||
},
|
||||
])
|
||||
expect(params).toEqual({
|
||||
tags__id__all: tags__id__all + ',14',
|
||||
})
|
||||
|
||||
params = queryParamsFromFilterRules(null)
|
||||
expect(params).toBeNull()
|
||||
})
|
||||
|
||||
it('should convert filter rules to query params', () => {
|
||||
let rules = filterRulesFromQueryParams(
|
||||
convertToParamMap({
|
||||
tags__id__all,
|
||||
})
|
||||
)
|
||||
expect(rules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: tags__id__all,
|
||||
},
|
||||
])
|
||||
|
||||
rules = filterRulesFromQueryParams(
|
||||
convertToParamMap({
|
||||
tags__id__all: tags__id__all + ',13',
|
||||
})
|
||||
)
|
||||
expect(rules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: tags__id__all,
|
||||
},
|
||||
{
|
||||
rule_type: FILTER_HAS_TAGS_ALL,
|
||||
value: '13',
|
||||
},
|
||||
])
|
||||
|
||||
rules = filterRulesFromQueryParams(
|
||||
convertToParamMap({
|
||||
correspondent__id: '12',
|
||||
})
|
||||
)
|
||||
expect(rules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_CORRESPONDENT,
|
||||
value: '12',
|
||||
},
|
||||
])
|
||||
|
||||
rules = filterRulesFromQueryParams(
|
||||
convertToParamMap({
|
||||
is_tagged: 'true',
|
||||
})
|
||||
)
|
||||
expect(rules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_HAS_ANY_TAG,
|
||||
value: 'true',
|
||||
},
|
||||
])
|
||||
|
||||
rules = filterRulesFromQueryParams(
|
||||
convertToParamMap({
|
||||
correspondent__isnull: '1',
|
||||
})
|
||||
)
|
||||
expect(rules).toEqual([
|
||||
{
|
||||
rule_type: FILTER_CORRESPONDENT,
|
||||
value: null,
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
@@ -18,7 +18,7 @@ export function paramsFromViewState(
|
||||
params[PAGE_PARAMETER] = isNaN(viewState.currentPage)
|
||||
? 1
|
||||
: viewState.currentPage
|
||||
if (pageOnly && viewState.currentPage == 1) params[PAGE_PARAMETER] = null
|
||||
if (pageOnly && viewState.currentPage == 1) params[PAGE_PARAMETER] = undefined
|
||||
return params
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user