11// biome-ignore assist/source/organizeImports: import mocks first
22import * as data from "./mocks/data" ;
33
4- import { rmSync } from "node:fs" ;
5-
4+ import { rmSync , writeFileSync } from "node:fs" ;
5+ import { join } from "node:path" ;
66import type { IncomingMessage , OutgoingHttpHeader , OutgoingHttpHeaders , RequestListener , Server , ServerResponse } from "node:http" ;
77import type { findAllDevices } from "zigbee-herdsman/dist/adapter/adapterDiscovery" ;
88import { onboard } from "../lib/util/onboarding" ;
@@ -752,7 +752,13 @@ describe("Onboarding", () => {
752752 } ) ;
753753
754754 it ( "handles validation failure" , async ( ) => {
755- settings . set ( [ "serial" , "adapter" ] , "emberz" ) ;
755+ const reReadSpy = vi . spyOn ( settings , "reRead" ) ;
756+
757+ // set after onboarding server is done to reach bottom code path
758+ reReadSpy . mockImplementationOnce ( ( ) => {
759+ settings . set ( [ "serial" , "adapter" ] , "emberz" ) ;
760+ settings . reRead ( ) ;
761+ } ) ;
756762
757763 let p ;
758764 const getHtml = await new Promise < string > ( ( resolve , reject ) => {
@@ -769,6 +775,88 @@ describe("Onboarding", () => {
769775
770776 await expect ( p ) . resolves . toStrictEqual ( false ) ;
771777 expect ( getHtml ) . toContain ( "adapter must be equal to one of the allowed values" ) ;
778+
779+ reReadSpy . mockRestore ( ) ;
780+ } ) ;
781+
782+ it ( "handles non-required validation failure before applying envs" , async ( ) => {
783+ settings . set ( [ "serial" ] , "/dev/ttyUSB0" ) ;
784+
785+ let p ;
786+ const getHtml = await new Promise < string > ( ( resolve , reject ) => {
787+ mockHttpOnListen . mockImplementationOnce ( async ( ) => {
788+ try {
789+ resolve ( await runFailure ( ) ) ;
790+ } catch ( error ) {
791+ reject ( error ) ;
792+ }
793+ } ) ;
794+
795+ p = onboard ( ) ;
796+ } ) ;
797+
798+ await expect ( p ) . resolves . toStrictEqual ( false ) ;
799+ expect ( getHtml ) . toContain ( "serial must be object" ) ;
800+ } ) ;
801+
802+ it ( "handles invalid yaml file" , async ( ) => {
803+ settings . testing . clear ( ) ;
804+
805+ const configFile = join ( data . mockDir , "configuration.yaml" ) ;
806+
807+ writeFileSync (
808+ configFile ,
809+ `
810+ good: 9
811+ \t wrong
812+ ` ,
813+ ) ;
814+
815+ let p ;
816+ const getHtml = await new Promise < string > ( ( resolve , reject ) => {
817+ mockHttpOnListen . mockImplementationOnce ( async ( ) => {
818+ try {
819+ resolve ( await runFailure ( ) ) ;
820+ } catch ( error ) {
821+ reject ( error ) ;
822+ }
823+ } ) ;
824+
825+ p = onboard ( ) ;
826+ } ) ;
827+
828+ await expect ( p ) . resolves . toStrictEqual ( false ) ;
829+ expect ( getHtml ) . toContain ( "Your configuration file" ) ;
830+ expect ( getHtml ) . toContain ( "is invalid" ) ;
831+
832+ data . removeConfiguration ( ) ;
833+ } ) ;
834+
835+ it ( "handles error while loading yaml file" , async ( ) => {
836+ settings . testing . clear ( ) ;
837+
838+ const configFile = join ( data . mockDir , "configuration.yaml" ) ;
839+
840+ writeFileSync ( configFile , "badfile" ) ;
841+
842+ let p ;
843+ const getHtml = await new Promise < string > ( ( resolve , reject ) => {
844+ mockHttpOnListen . mockImplementationOnce ( async ( ) => {
845+ try {
846+ resolve ( await runFailure ( ) ) ;
847+ } catch ( error ) {
848+ reject ( error ) ;
849+ }
850+ } ) ;
851+
852+ p = onboard ( ) ;
853+ } ) ;
854+
855+ await expect ( p ) . resolves . toStrictEqual ( false ) ;
856+ expect ( getHtml ) . toContain ( "AssertionError" ) ;
857+ expect ( getHtml ) . toContain ( "expected to be an object" ) ;
858+
859+ data . removeConfiguration ( ) ;
772860 } ) ;
773861
774862 it ( "handles creating data path" , async ( ) => {
0 commit comments