1+ /*
2+ * SPDX-FileCopyrightText: 2026 LibreSign contributors
3+ * SPDX-License-Identifier: AGPL-3.0-or-later
4+ */
5+
6+ import { beforeEach , describe , expect , it , vi } from 'vitest'
7+ import { mount } from '@vue/test-utils'
8+
9+ import CertificateCustonOptions from '../../../views/Settings/CertificateCustonOptions.vue'
10+
11+ const emitMock = vi . fn ( )
12+
13+ vi . mock ( '@nextcloud/event-bus' , ( ) => ( {
14+ emit : ( ...args : unknown [ ] ) => emitMock ( ...args ) ,
15+ } ) )
16+
17+ vi . mock ( '@nextcloud/l10n' , ( ) => ( {
18+ t : vi . fn ( ( _app : string , text : string , vars ?: Record < string , string | number > ) => {
19+ if ( ! vars ) {
20+ return text
21+ }
22+ return Object . entries ( vars ) . reduce ( ( message , [ key , value ] ) => message . replace ( `{${ key } }` , String ( value ) ) , text )
23+ } ) ,
24+ translate : vi . fn ( ( _app : string , text : string ) => text ) ,
25+ translatePlural : vi . fn ( ( _app : string , singular : string , plural : string , count : number ) => ( count === 1 ? singular : plural ) ) ,
26+ n : vi . fn ( ( _app : string , singular : string , plural : string , count : number ) => ( count === 1 ? singular : plural ) ) ,
27+ isRTL : vi . fn ( ( ) => false ) ,
28+ getLanguage : vi . fn ( ( ) => 'en' ) ,
29+ getLocale : vi . fn ( ( ) => 'en' ) ,
30+ } ) )
31+
32+ describe ( 'CertificateCustonOptions.vue' , ( ) => {
33+ beforeEach ( ( ) => {
34+ emitMock . mockReset ( )
35+ } )
36+
37+ function createWrapper ( names : Array < Record < string , unknown > > = [ ] ) {
38+ return mount ( CertificateCustonOptions , {
39+ props : { names } ,
40+ global : {
41+ stubs : {
42+ NcButton : { template : '<button><slot /><slot name="icon" /></button>' } ,
43+ NcIconSvgWrapper : true ,
44+ NcListItem : { template : '<div><slot name="subname" /><slot /></div>' } ,
45+ NcPopover : { template : '<div><slot name="trigger" /><slot /></div>' } ,
46+ NcTextField : {
47+ props : [ 'modelValue' ] ,
48+ emits : [ 'update:modelValue' ] ,
49+ template : '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)">' ,
50+ } ,
51+ } ,
52+ } ,
53+ } )
54+ }
55+
56+ it ( 'initializes certificateList from names and filters already selected options' , ( ) => {
57+ const wrapper = createWrapper ( [ { id : 'O' , value : 'LibreSign' } ] )
58+
59+ expect ( wrapper . vm . certificateList ) . toEqual ( [ { id : 'O' , value : 'LibreSign' } ] )
60+ expect ( wrapper . vm . customNamesOptions . map ( ( option : { id : string } ) => option . id ) ) . not . toContain ( 'O' )
61+ expect ( wrapper . vm . customNamesOptions . map ( ( option : { id : string } ) => option . id ) ) . not . toContain ( 'CN' )
62+ expect ( wrapper . vm . customNamesOptions . map ( ( option : { id : string } ) => option . id ) ) . toContain ( 'OU' )
63+ } )
64+
65+ it ( 'adds OU as an array-backed option' , async ( ) => {
66+ const wrapper = createWrapper ( )
67+
68+ await wrapper . vm . onOptionalAttributeSelect ( { id : 'OU' } )
69+
70+ expect ( wrapper . vm . certificateList ) . toEqual ( [
71+ expect . objectContaining ( {
72+ id : 'OU' ,
73+ value : [ '' ] ,
74+ } ) ,
75+ ] )
76+ } )
77+
78+ it ( 'emits updated list when validating and editing OU array entries' , async ( ) => {
79+ const wrapper = createWrapper ( [ { id : 'OU' , value : [ 'Security' ] } ] )
80+
81+ await wrapper . vm . addArrayEntry ( 'OU' )
82+ expect ( emitMock ) . toHaveBeenLastCalledWith ( 'libresign:update:certificateToSave' , [
83+ { id : 'OU' , value : [ 'Security' , '' ] } ,
84+ ] )
85+
86+ await wrapper . vm . removeArrayEntry ( 'OU' , 1 )
87+ expect ( emitMock ) . toHaveBeenLastCalledWith ( 'libresign:update:certificateToSave' , [
88+ { id : 'OU' , value : [ 'Security' ] } ,
89+ ] )
90+ } )
91+
92+ it ( 'marks invalid values and emits sanitized payload on validate' , async ( ) => {
93+ const wrapper = createWrapper ( [ { id : 'C' , value : 'B' } ] )
94+
95+ await wrapper . vm . validate ( 'C' )
96+
97+ expect ( wrapper . vm . certificateList [ 0 ] . error ) . toBe ( true )
98+ expect ( emitMock ) . toHaveBeenLastCalledWith ( 'libresign:update:certificateToSave' , [
99+ { id : 'C' , value : 'B' } ,
100+ ] )
101+ } )
102+
103+ it ( 'removes selected custom attributes from the local list' , async ( ) => {
104+ const wrapper = createWrapper ( [
105+ { id : 'O' , value : 'LibreSign' } ,
106+ { id : 'OU' , value : [ 'Security' ] } ,
107+ ] )
108+
109+ await wrapper . vm . removeOptionalAttribute ( 'O' )
110+
111+ expect ( wrapper . vm . certificateList ) . toEqual ( [
112+ { id : 'OU' , value : [ 'Security' ] } ,
113+ ] )
114+ } )
115+ } )
0 commit comments