11const { getState } = require ( "@saltcorn/data/db/state" ) ;
22const View = require ( "@saltcorn/data/models/view" ) ;
33const { mockReqRes } = require ( "@saltcorn/data/tests/mocks" ) ;
4+ const { hashState } = require ( "@saltcorn/data/utils" ) ;
45const { afterAll, beforeAll, describe, it, expect } = require ( "@jest/globals" ) ;
56
67getState ( ) . registerPlugin ( "base" , require ( "@saltcorn/data/base-plugin" ) ) ;
@@ -11,6 +12,11 @@ beforeAll(async () => {
1112 await getState ( ) . refresh ( true ) ;
1213} ) ;
1314
15+ const extractAttr = ( html , attr ) => {
16+ const m = html . match ( new RegExp ( `${ attr } ="([^"]*)"` ) ) ;
17+ return m ? m [ 1 ] : null ;
18+ } ;
19+
1420describe ( "react view run tests" , ( ) => {
1521 it ( "run tableless view" , async ( ) => {
1622 const view = View . findOne ( { name : "default_react_view" } ) ;
@@ -43,3 +49,43 @@ describe("react view run tests", () => {
4349 expect ( result ) . toContain ( 'timestamp="' ) ;
4450 } ) ;
4551} ) ;
52+
53+ describe ( "stateHash prop tests" , ( ) => {
54+ it ( "tableless view exposes state-hash as a 5-char hex string" , async ( ) => {
55+ const view = View . findOne ( { name : "default_react_view" } ) ;
56+ const result = await view . run ( { } , mockReqRes ) ;
57+ expect ( result ) . toContain ( 'state-hash="' ) ;
58+ const hash = extractAttr ( result , "state-hash" ) ;
59+ expect ( hash ) . toMatch ( / ^ [ 0 - 9 a - f ] { 5 } $ / ) ;
60+ } ) ;
61+
62+ it ( "table-based view exposes state-hash as a 5-char hex string" , async ( ) => {
63+ const view = View . findOne ( { name : "react_view_with_data" } ) ;
64+ const result = await view . run ( { } , mockReqRes ) ;
65+ expect ( result ) . toContain ( 'state-hash="' ) ;
66+ const hash = extractAttr ( result , "state-hash" ) ;
67+ expect ( hash ) . toMatch ( / ^ [ 0 - 9 a - f ] { 5 } $ / ) ;
68+ } ) ;
69+
70+ it ( "state-hash matches hashState utility output" , async ( ) => {
71+ const view = View . findOne ( { name : "react_view_with_data" } ) ;
72+ const state = { } ;
73+ const result = await view . run ( state , mockReqRes ) ;
74+ const hash = extractAttr ( result , "state-hash" ) ;
75+ expect ( hash ) . toBe ( hashState ( state , "react_view_with_data" ) ) ;
76+ } ) ;
77+
78+ it ( "state-hash is stable when only pagination params change" , async ( ) => {
79+ const view = View . findOne ( { name : "react_view_with_data" } ) ;
80+ const baseState = { } ;
81+ const baseResult = await view . run ( baseState , mockReqRes ) ;
82+ const baseHash = extractAttr ( baseResult , "state-hash" ) ;
83+
84+ const baseHashValue = hashState ( baseState , "react_view_with_data" ) ;
85+ const pagedState = { [ `_${ baseHashValue } _page` ] : "2" } ;
86+ const pagedResult = await view . run ( pagedState , mockReqRes ) ;
87+ const pagedHash = extractAttr ( pagedResult , "state-hash" ) ;
88+
89+ expect ( pagedHash ) . toBe ( baseHash ) ;
90+ } ) ;
91+ } ) ;
0 commit comments