11import { BaseControllerHost } from "@mendix/widget-plugin-mobx-kit/BaseControllerHost" ;
22import { GateProvider } from "@mendix/widget-plugin-mobx-kit/GateProvider" ;
33// import { ReactiveControllerHost } from "@mendix/widget-plugin-mobx-kit/main";
4- import { list } from "@mendix/widget-plugin-test-utils" ;
4+ import { list , obj } from "@mendix/widget-plugin-test-utils" ;
55import { ListValue } from "mendix" ;
66import { DatasourceController } from "../query/DatasourceController" ;
77
@@ -26,31 +26,40 @@ describe("DatasourceController loading states", () => {
2626 provider . setProps ( { datasource, refreshIndicator : false , refreshInterval : 0 } ) ;
2727 } ) ;
2828
29- it ( "isFirstLoad returns true by default " , ( ) => {
29+ it ( "isFirstLoad returns true when loading and items undefined " , ( ) => {
3030 expect ( controller . isFirstLoad ) . toBe ( true ) ;
3131 } ) ;
3232
33- it ( "refresh has no effect if ds is loading" , ( ) => {
34- expect ( provider . gate . props . datasource . status ) . toBe ( "loading ") ;
33+ it ( "backgroundRefresh does not trigger reload if already loading" , ( ) => {
34+ const reloadSpy = jest . spyOn ( provider . gate . props . datasource , "reload ") ;
3535 controller . backgroundRefresh ( ) ;
36+ expect ( reloadSpy ) . not . toHaveBeenCalled ( ) ;
37+ } ) ;
38+
39+ it ( "isRefreshing is false when loading and items undefined" , ( ) => {
3640 expect ( controller . isRefreshing ) . toBe ( false ) ;
3741 } ) ;
3842
39- it ( "isRefreshing is true after refresh call" , ( ) => {
40- provider . setProps ( { datasource : list ( 0 ) , refreshIndicator : false , refreshInterval : 0 } ) ;
41- expect ( provider . gate . props . datasource . status ) . toBe ( "available" ) ;
43+ it ( "isRefreshing is true after backgroundRefresh when items are present" , ( ) => {
44+ // Set datasource to available with items
45+ provider . setProps ( { datasource : list ( 1 ) , refreshIndicator : false , refreshInterval : 0 } ) ;
46+ // Simulate refresh
4247 controller . backgroundRefresh ( ) ;
48+ // Replace datasource with a mock in loading state and items present
49+ const loadingWithItems = { ...list . loading ( ) , items : [ obj ( ) ] } ;
50+ provider . setProps ( { datasource : loadingWithItems , refreshIndicator : false , refreshInterval : 0 } ) ;
4351 expect ( controller . isRefreshing ) . toBe ( true ) ;
44- provider . setProps ( { datasource : list . loading ( ) , refreshIndicator : false , refreshInterval : 0 } ) ;
45- expect ( provider . gate . props . datasource . status ) . toBe ( "loading" ) ;
46- expect ( controller . isRefreshing ) . toBe ( true ) ;
47- expect ( controller . isFirstLoad ) . toBe ( false ) ;
4852 } ) ;
4953
50- it ( "isFetchingNextBatch returns true after setLimit call" , ( ) => {
54+ it ( "isFetchingNextBatch is true after setLimit call" , ( ) => {
5155 controller . setLimit ( 20 ) ;
5256 expect ( controller . isFetchingNextBatch ) . toBe ( true ) ;
53- expect ( controller . isFirstLoad ) . toBe ( true ) ;
57+ } ) ;
58+
59+ it ( "isSilentRefresh is true after backgroundRefresh" , ( ) => {
60+ provider . setProps ( { datasource : list ( 1 ) , refreshIndicator : false , refreshInterval : 0 } ) ;
61+ controller . backgroundRefresh ( ) ;
62+ expect ( controller . isSilentRefresh ) . toBe ( true ) ;
5463 } ) ;
5564 } ) ;
5665
@@ -64,16 +73,62 @@ describe("DatasourceController loading states", () => {
6473 expect ( controller . isFirstLoad ) . toBe ( false ) ;
6574 expect ( controller . isRefreshing ) . toBe ( false ) ;
6675 expect ( controller . isFetchingNextBatch ) . toBe ( false ) ;
76+ expect ( controller . isSilentRefresh ) . toBe ( false ) ;
6777 } ) ;
6878
69- it ( "triggers refresh when called" , ( ) => {
79+ it ( "backgroundRefresh triggers reload when not loading" , ( ) => {
80+ const reloadSpy = jest . spyOn ( datasource , "reload" ) ;
7081 controller . backgroundRefresh ( ) ;
71- expect ( datasource . reload ) . toHaveBeenCalled ( ) ;
82+ expect ( reloadSpy ) . toHaveBeenCalled ( ) ;
7283 } ) ;
7384
74- it ( "triggers setLimit when called" , ( ) => {
85+ it ( "setLimit triggers setLimit on datasource" , ( ) => {
86+ const setLimitSpy = jest . spyOn ( datasource , "setLimit" ) ;
7587 controller . setLimit ( 20 ) ;
76- expect ( datasource . setLimit ) . toHaveBeenCalledWith ( 20 ) ;
88+ expect ( setLimitSpy ) . toHaveBeenCalledWith ( 20 ) ;
89+ } ) ;
90+
91+ it ( "setOffset triggers setOffset and resets flags" , ( ) => {
92+ const setOffsetSpy = jest . spyOn ( datasource , "setOffset" ) ;
93+ controller . setOffset ( 5 ) ;
94+ expect ( setOffsetSpy ) . toHaveBeenCalledWith ( 5 ) ;
95+ } ) ;
96+
97+ it ( "setSortOrder triggers setSortOrder and resets flags" , ( ) => {
98+ const setSortOrderSpy = jest . spyOn ( datasource , "setSortOrder" ) ;
99+ // Use Mendix Option_2 structure (runtime shape)
100+ const sortOption = { some : [ { attribute : "name" , direction : "asc" } ] } ;
101+ // @ts -expect-error: Mendix Option_2 type not available in workspace
102+ controller . setSortOrder ( sortOption ) ;
103+ expect ( setSortOrderSpy ) . toHaveBeenCalledWith ( sortOption ) ;
104+ } ) ;
105+
106+ it ( "setFilter triggers setFilter and resets flags" , ( ) => {
107+ const setFilterSpy = jest . spyOn ( datasource , "setFilter" ) ;
108+ // Use Mendix Option_2 structure (runtime shape)
109+ const filterOption = { some : { attribute : "name" , operator : "equals" , value : "test" } } ;
110+ // @ts -expect-error: Mendix Option_2 type not available in workspace
111+ controller . setFilter ( filterOption ) ;
112+ expect ( setFilterSpy ) . toHaveBeenCalledWith ( filterOption ) ;
113+ } ) ;
114+
115+ it ( "setPageSize updates pageSize property" , ( ) => {
116+ controller . setPageSize ( 50 ) ;
117+ // @ts -expect-error: private property
118+ expect ( controller . pageSize ) . toBe ( 50 ) ;
119+ } ) ;
120+
121+ it ( "requestTotalCount triggers datasource.requestTotalCount" , ( ) => {
122+ const spy = jest . spyOn ( datasource , "requestTotalCount" ) ;
123+ controller . requestTotalCount ( true ) ;
124+ expect ( spy ) . toHaveBeenCalledWith ( true ) ;
125+ } ) ;
126+
127+ it ( "derivedQuery returns a computed value and updates on datasource change" , ( ) => {
128+ const derived = controller . derivedQuery ;
129+ expect ( typeof derived . get ) . toBe ( "function" ) ;
130+ provider . setProps ( { datasource : list ( 2 ) , refreshIndicator : false , refreshInterval : 0 } ) ;
131+ expect ( derived . get ( ) ) . toBeInstanceOf ( DatasourceController ) ;
77132 } ) ;
78133 } ) ;
79134} ) ;
0 commit comments