@openui5/sap.ui.core 1.115.1 → 1.116.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/.dtsgenrc +18 -0
  2. package/.eslintrc.json +11 -0
  3. package/.reuse/dep5 +0 -5
  4. package/THIRDPARTY.txt +1 -7
  5. package/package.json +1 -1
  6. package/src/jquery.sap.global.js +1 -1
  7. package/src/jquery.sap.properties.js +1 -1
  8. package/src/jquery.sap.resources.js +1 -1
  9. package/src/jquery.sap.script.js +1 -1
  10. package/src/jquery.sap.sjax.js +2 -2
  11. package/src/jquery.sap.storage.js +3 -3
  12. package/src/sap/base/Event.js +106 -0
  13. package/src/sap/base/Eventing.js +320 -0
  14. package/src/sap/base/config.js +1 -1
  15. package/src/sap/base/i18n/Formatting.js +991 -0
  16. package/src/sap/base/i18n/LanguageTag.js +189 -0
  17. package/src/sap/base/i18n/Localization.js +711 -0
  18. package/src/sap/base/i18n/ResourceBundle.js +5 -20
  19. package/src/sap/base/i18n/date/CalendarType.js +54 -0
  20. package/src/sap/base/i18n/date/CalendarWeekNumbering.js +105 -0
  21. package/src/sap/base/i18n/date/TimezoneUtils.js +287 -0
  22. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  23. package/src/sap/base/util/restricted/_castArray.js +1 -1
  24. package/src/sap/base/util/restricted/_compact.js +1 -1
  25. package/src/sap/base/util/restricted/_curry.js +1 -1
  26. package/src/sap/base/util/restricted/_debounce.js +1 -1
  27. package/src/sap/base/util/restricted/_difference.js +1 -1
  28. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  29. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  30. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  31. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  32. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  33. package/src/sap/base/util/restricted/_flatten.js +1 -1
  34. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  35. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  36. package/src/sap/base/util/restricted/_intersection.js +1 -1
  37. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  38. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  39. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  40. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  41. package/src/sap/base/util/restricted/_isNil.js +1 -1
  42. package/src/sap/base/util/restricted/_max.js +1 -1
  43. package/src/sap/base/util/restricted/_merge.js +1 -1
  44. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  45. package/src/sap/base/util/restricted/_min.js +1 -1
  46. package/src/sap/base/util/restricted/_omit.js +1 -1
  47. package/src/sap/base/util/restricted/_pick.js +1 -1
  48. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  49. package/src/sap/base/util/restricted/_throttle.js +1 -1
  50. package/src/sap/base/util/restricted/_toArray.js +1 -1
  51. package/src/sap/base/util/restricted/_union.js +1 -1
  52. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  53. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  54. package/src/sap/base/util/restricted/_uniq.js +1 -1
  55. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  56. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  57. package/src/sap/base/util/restricted/_without.js +1 -1
  58. package/src/sap/base/util/restricted/_xor.js +1 -1
  59. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  60. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  61. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  62. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  63. package/src/sap/ui/Device.js +3 -3
  64. package/src/sap/ui/Global.js +4 -4
  65. package/src/sap/ui/base/Event.js +1 -1
  66. package/src/sap/ui/base/EventProvider.js +4 -12
  67. package/src/sap/ui/base/Interface.js +1 -1
  68. package/src/sap/ui/base/ManagedObject.js +8 -12
  69. package/src/sap/ui/base/ManagedObjectMetadata.js +30 -7
  70. package/src/sap/ui/base/Metadata.js +1 -1
  71. package/src/sap/ui/base/Object.js +1 -1
  72. package/src/sap/ui/base/ObjectPool.js +1 -1
  73. package/src/sap/ui/base/SyncPromise.js +10 -5
  74. package/src/sap/ui/core/.library +2 -2
  75. package/src/sap/ui/core/AccessKeysEnablement.js +10 -5
  76. package/src/sap/ui/core/AnimationMode.js +49 -0
  77. package/src/sap/ui/core/BusyIndicator.js +33 -42
  78. package/src/sap/ui/core/CalendarType.js +11 -37
  79. package/src/sap/ui/core/Component.js +4 -5
  80. package/src/sap/ui/core/ComponentContainer.js +1 -1
  81. package/src/sap/ui/core/ComponentMetadata.js +2 -2
  82. package/src/sap/ui/core/ComponentSupport.js +1 -1
  83. package/src/sap/ui/core/Configuration.js +409 -1270
  84. package/src/sap/ui/core/Control.js +4 -12
  85. package/src/sap/ui/core/ControlBehavior.js +157 -0
  86. package/src/sap/ui/core/Core.js +124 -132
  87. package/src/sap/ui/core/CustomData.js +1 -1
  88. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  89. package/src/sap/ui/core/Element.js +14 -3
  90. package/src/sap/ui/core/ElementMetadata.js +1 -1
  91. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  92. package/src/sap/ui/core/EventBus.js +1 -1
  93. package/src/sap/ui/core/Fragment.js +1 -1
  94. package/src/sap/ui/core/HTML.js +1 -1
  95. package/src/sap/ui/core/History.js +1 -1
  96. package/src/sap/ui/core/Icon.js +1 -1
  97. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  98. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  99. package/src/sap/ui/core/InvisibleMessage.js +5 -7
  100. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  101. package/src/sap/ui/core/InvisibleText.js +12 -12
  102. package/src/sap/ui/core/Item.js +1 -1
  103. package/src/sap/ui/core/LabelEnablement.js +1 -1
  104. package/src/sap/ui/core/LayoutData.js +1 -1
  105. package/src/sap/ui/core/Lib.js +109 -22
  106. package/src/sap/ui/core/ListItem.js +1 -1
  107. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  108. package/src/sap/ui/core/Locale.js +151 -430
  109. package/src/sap/ui/core/LocaleData.js +39 -11
  110. package/src/sap/ui/core/Manifest.js +1 -1
  111. package/src/sap/ui/core/Message.js +1 -1
  112. package/src/sap/ui/core/RenderManager.js +1 -1
  113. package/src/sap/ui/core/Renderer.js +1 -1
  114. package/src/sap/ui/core/ResizeHandler.js +1 -1
  115. package/src/sap/ui/core/ScrollBar.js +1 -1
  116. package/src/sap/ui/core/SeparatorItem.js +1 -1
  117. package/src/sap/ui/core/StaticArea.js +31 -17
  118. package/src/sap/ui/core/Theming.js +451 -0
  119. package/src/sap/ui/core/Title.js +1 -1
  120. package/src/sap/ui/core/TooltipBase.js +1 -1
  121. package/src/sap/ui/core/UIArea.js +1 -1
  122. package/src/sap/ui/core/UIComponent.js +1 -1
  123. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  124. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  125. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  126. package/src/sap/ui/core/XMLComposite.js +1 -1
  127. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  128. package/src/sap/ui/core/XMLTemplateProcessor.js +1 -0
  129. package/src/sap/ui/core/_IconRegistry.js +7 -1
  130. package/src/sap/ui/core/date/CalendarWeekNumbering.js +12 -83
  131. package/src/sap/ui/core/date/UI5Date.js +2 -2
  132. package/src/sap/ui/core/delegate/ItemNavigation.js +8 -10
  133. package/src/sap/ui/core/delegate/ScrollEnablement.js +5 -5
  134. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  135. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  136. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  137. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  138. package/src/sap/ui/core/format/DateFormat.js +20 -15
  139. package/src/sap/ui/core/format/TimezoneUtil.js +15 -273
  140. package/src/sap/ui/core/hyphenation/Hyphenation.js +1 -1
  141. package/src/sap/ui/core/library.js +3 -3
  142. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  143. package/src/sap/ui/core/message/Message.js +1 -1
  144. package/src/sap/ui/core/message/MessageManager.js +1 -1
  145. package/src/sap/ui/core/message/MessageParser.js +1 -1
  146. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  147. package/src/sap/ui/core/messagebundle_cs.properties +1 -1
  148. package/src/sap/ui/core/messagebundle_cy.properties +1 -1
  149. package/src/sap/ui/core/messagebundle_da.properties +1 -1
  150. package/src/sap/ui/core/messagebundle_de.properties +1 -1
  151. package/src/sap/ui/core/messagebundle_el.properties +1 -1
  152. package/src/sap/ui/core/messagebundle_en.properties +1 -1
  153. package/src/sap/ui/core/messagebundle_en_GB.properties +1 -1
  154. package/src/sap/ui/core/messagebundle_es.properties +1 -1
  155. package/src/sap/ui/core/messagebundle_es_MX.properties +1 -1
  156. package/src/sap/ui/core/messagebundle_et.properties +1 -1
  157. package/src/sap/ui/core/messagebundle_id.properties +1 -1
  158. package/src/sap/ui/core/messagebundle_it.properties +49 -49
  159. package/src/sap/ui/core/messagebundle_iw.properties +1 -1
  160. package/src/sap/ui/core/messagebundle_kk.properties +1 -1
  161. package/src/sap/ui/core/messagebundle_ko.properties +1 -1
  162. package/src/sap/ui/core/messagebundle_lt.properties +1 -1
  163. package/src/sap/ui/core/messagebundle_lv.properties +1 -1
  164. package/src/sap/ui/core/messagebundle_ms.properties +8 -8
  165. package/src/sap/ui/core/messagebundle_nl.properties +1 -1
  166. package/src/sap/ui/core/messagebundle_no.properties +1 -1
  167. package/src/sap/ui/core/messagebundle_pl.properties +1 -1
  168. package/src/sap/ui/core/messagebundle_pt.properties +1 -1
  169. package/src/sap/ui/core/messagebundle_pt_PT.properties +1 -1
  170. package/src/sap/ui/core/messagebundle_ro.properties +1 -1
  171. package/src/sap/ui/core/messagebundle_sh.properties +1 -1
  172. package/src/sap/ui/core/messagebundle_sv.properties +1 -1
  173. package/src/sap/ui/core/messagebundle_th.properties +1 -1
  174. package/src/sap/ui/core/messagebundle_uk.properties +21 -21
  175. package/src/sap/ui/core/messagebundle_vi.properties +1 -1
  176. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  177. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  178. package/src/sap/ui/core/mvc/JSView.js +1 -1
  179. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  180. package/src/sap/ui/core/mvc/View.js +1 -1
  181. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  182. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  183. package/src/sap/ui/core/plugin/LessSupport.js +14 -16
  184. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  185. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  186. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  187. package/src/sap/ui/core/routing/HashChanger.js +1 -0
  188. package/src/sap/ui/core/routing/Route.js +1 -0
  189. package/src/sap/ui/core/routing/Router.js +3 -1
  190. package/src/sap/ui/core/rules/Config.support.js +2 -2
  191. package/src/sap/ui/core/rules/Model.support.js +3 -1
  192. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  193. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  194. package/src/sap/ui/core/service/Service.js +1 -1
  195. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  196. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  197. package/src/sap/ui/core/support/Plugin.js +1 -1
  198. package/src/sap/ui/core/support/Support.js +1 -1
  199. package/src/sap/ui/core/support/controls/TimelineOverview.js +1 -1
  200. package/src/sap/ui/core/support/plugins/ControlTree.js +2 -2
  201. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  202. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  203. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  204. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  205. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  206. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  207. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  208. package/src/sap/ui/core/themes/base/LocalBusyIndicator.less +4 -4
  209. package/src/sap/ui/core/themes/base/base.less +41 -20
  210. package/src/sap/ui/core/themes/base/fonts/SAP-icons.ttf +0 -0
  211. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  212. package/src/sap/ui/core/theming/Parameters.js +6 -5
  213. package/src/sap/ui/core/theming/ThemeManager.js +310 -447
  214. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  215. package/src/sap/ui/core/tmpl/DOMElement.js +5 -10
  216. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  217. package/src/sap/ui/core/tmpl/Template.js +1 -1
  218. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  219. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  220. package/src/sap/ui/core/util/Export.js +1 -1
  221. package/src/sap/ui/core/util/ExportCell.js +1 -1
  222. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  223. package/src/sap/ui/core/util/ExportRow.js +1 -1
  224. package/src/sap/ui/core/util/ExportType.js +1 -1
  225. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  226. package/src/sap/ui/core/util/File.js +1 -1
  227. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  228. package/src/sap/ui/core/util/MockServer.js +1 -1
  229. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  230. package/src/sap/ui/core/util/reflection/BaseTreeModifier.js +3 -1
  231. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  232. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  233. package/src/sap/ui/core/util/serializer/ViewSerializer.js +1 -1
  234. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  235. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  236. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  237. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  238. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  239. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  240. package/src/sap/ui/core/ws/WebSocket.js +1 -1
  241. package/src/sap/ui/debug/ControlTree.js +1 -1
  242. package/src/sap/ui/debug/DebugEnv.js +1 -1
  243. package/src/sap/ui/debug/PropertyList.js +1 -1
  244. package/src/sap/ui/events/PseudoEvents.js +17 -9
  245. package/src/sap/ui/model/Binding.js +19 -15
  246. package/src/sap/ui/model/ClientModel.js +1 -1
  247. package/src/sap/ui/model/CompositeBinding.js +57 -19
  248. package/src/sap/ui/model/CompositeDataState.js +1 -1
  249. package/src/sap/ui/model/CompositeType.js +1 -1
  250. package/src/sap/ui/model/DataState.js +1 -1
  251. package/src/sap/ui/model/ListBinding.js +42 -1
  252. package/src/sap/ui/model/MetaModel.js +1 -1
  253. package/src/sap/ui/model/Model.js +5 -4
  254. package/src/sap/ui/model/PropertyBinding.js +10 -0
  255. package/src/sap/ui/model/SelectionModel.js +1 -1
  256. package/src/sap/ui/model/SimpleType.js +4 -1
  257. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  258. package/src/sap/ui/model/Type.js +1 -1
  259. package/src/sap/ui/model/base/ManagedObjectModel.js +1 -1
  260. package/src/sap/ui/model/json/JSONModel.js +1 -1
  261. package/src/sap/ui/model/message/MessageModel.js +1 -1
  262. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  263. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  264. package/src/sap/ui/model/odata/ODataMetaModel.js +1 -1
  265. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  266. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  267. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  268. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  269. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  270. package/src/sap/ui/model/odata/type/Date.js +1 -1
  271. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  272. package/src/sap/ui/model/odata/type/DateTimeBase.js +8 -1
  273. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  274. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +1 -1
  275. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  276. package/src/sap/ui/model/odata/type/Double.js +1 -1
  277. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  278. package/src/sap/ui/model/odata/type/Int.js +1 -1
  279. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  280. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  281. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  282. package/src/sap/ui/model/odata/type/ODataType.js +3 -3
  283. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  284. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  285. package/src/sap/ui/model/odata/type/Single.js +1 -1
  286. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  287. package/src/sap/ui/model/odata/type/String.js +1 -1
  288. package/src/sap/ui/model/odata/type/Time.js +1 -1
  289. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  290. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  291. package/src/sap/ui/model/odata/v2/Context.js +3 -2
  292. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +1 -1
  293. package/src/sap/ui/model/odata/v2/ODataListBinding.js +14 -3
  294. package/src/sap/ui/model/odata/v2/ODataModel.js +45 -31
  295. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  296. package/src/sap/ui/model/odata/v4/Context.js +7 -3
  297. package/src/sap/ui/model/odata/v4/ODataBinding.js +68 -39
  298. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +12 -8
  299. package/src/sap/ui/model/odata/v4/ODataListBinding.js +30 -8
  300. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +11 -9
  301. package/src/sap/ui/model/odata/v4/ODataModel.js +10 -14
  302. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +64 -31
  303. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +21 -16
  304. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +2 -0
  305. package/src/sap/ui/model/odata/v4/lib/_Cache.js +37 -14
  306. package/src/sap/ui/model/odata/v4/lib/_Helper.js +11 -1
  307. package/src/sap/ui/model/odata/v4/lib/_Requestor.js +7 -4
  308. package/src/sap/ui/model/odata/v4/lib/_V2MetadataConverter.js +4 -4
  309. package/src/sap/ui/model/odata/v4/lib/_V2Requestor.js +1 -1
  310. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  311. package/src/sap/ui/model/type/Boolean.js +1 -1
  312. package/src/sap/ui/model/type/Currency.js +1 -1
  313. package/src/sap/ui/model/type/Date.js +1 -1
  314. package/src/sap/ui/model/type/DateInterval.js +1 -1
  315. package/src/sap/ui/model/type/DateTime.js +1 -1
  316. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  317. package/src/sap/ui/model/type/FileSize.js +1 -1
  318. package/src/sap/ui/model/type/Float.js +1 -1
  319. package/src/sap/ui/model/type/Integer.js +1 -1
  320. package/src/sap/ui/model/type/String.js +1 -1
  321. package/src/sap/ui/model/type/Time.js +1 -1
  322. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  323. package/src/sap/ui/model/type/Unit.js +1 -1
  324. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  325. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  326. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  327. package/src/sap/ui/test/Opa5.js +1 -1
  328. package/src/sap/ui/test/autowaiter/_autoWaiter.js +1 -1
  329. package/src/sap/ui/test/generic/TestBase.js +1 -1
  330. package/src/sap/ui/test/gherkin/simpleGherkinParser.js +10 -5
  331. package/src/sap/ui/test/matchers/LabelFor.js +1 -0
  332. package/src/sap/ui/thirdparty/caja-html-sanitizer.js +111 -96
  333. package/src/sap/ui/util/ActivityDetection.js +7 -1
  334. package/src/sap/ui/util/Mobile.js +11 -8
  335. package/src/sap/ui/util/Storage.js +1 -1
  336. package/src/ui5loader-autoconfig.js +5 -2
  337. package/src/ui5loader.js +169 -185
  338. package/test/sap/ui/core/FormatHelper.js +3 -2
  339. package/test/sap/ui/core/demokit/docuindex.json +6 -0
  340. package/test/sap/ui/core/demokit/sample/OpaBusyIndicator/OpaBusyIndicator.js +1 -1
  341. package/test/sap/ui/core/demokit/sample/OpaMatchers/OpaMatchers.js +2 -2
  342. package/test/sap/ui/core/demokit/sample/ViewTemplate/types/MIT.ODataTypes.html +9 -14
  343. package/test/sap/ui/core/demokit/sample/ViewTemplate/types/Opa.qunit.js +7 -0
  344. package/test/sap/ui/core/demokit/sample/common/pages/Any.js +1 -1
  345. package/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/tests/filter.js +2 -2
  346. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/Component.js +27 -0
  347. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/ListReport.controller.js +43 -0
  348. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/ListReport.view.xml +47 -0
  349. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/Main.controller.js +27 -0
  350. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/Main.view.xml +7 -0
  351. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/NotFound.view.xml +8 -0
  352. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/ObjectPage.controller.js +123 -0
  353. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/ObjectPage.view.xml +92 -0
  354. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/Opa.qunit.html +27 -0
  355. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/Opa.qunit.js +69 -0
  356. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/README.html +55 -0
  357. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/SandboxModel.js +56 -0
  358. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/POST-SalesOrderList.json +66 -0
  359. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/SalesOrderList('0500000000')-SO_2_SOITEM.json +57 -0
  360. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/SalesOrderList('0500000000').json +20 -0
  361. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/SalesOrderList('0500000001').json +9 -0
  362. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/SalesOrderList('0500000007')-SO_2_BP.json +12 -0
  363. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/SalesOrderList.json +62 -0
  364. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/VH_CurrencyCode.json +85 -0
  365. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/VH_CurrencyCode.xml +185 -0
  366. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/VH_ProductID.json +93 -0
  367. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/VH_ProductID.xml +262 -0
  368. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/data/metadata.xml +1779 -0
  369. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/manifest.json +134 -0
  370. package/test/sap/ui/core/demokit/sample/odata/v4/DeepCreate/pages/Main.js +119 -0
  371. package/test/sap/ui/core/demokit/sample/odata/v4/MultipleInlineCreationRowsGrid/pages/Main.js +0 -41
  372. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V2/manifest.json +1 -1
  373. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V4/manifest.json +1 -1
  374. package/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/Main.controller.js +5 -17
  375. package/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/Main.view.xml +3 -3
  376. package/test/sap/ui/core/demokit/tutorial/odatav4/08/webapp/test/integration/arrangements/Startup.js +1 -1
  377. package/test/sap/ui/core/demokit/tutorial/odatav4/11/webapp/test/integration/arrangements/Startup.js +1 -1
  378. package/test/sap/ui/core/qunit/CompositeBinding.qunit.js +25 -7
  379. package/test/sap/ui/core/qunit/ControlRenderer.qunit.js +86 -2
  380. package/test/sap/ui/core/qunit/DataState.qunit.js +2 -7
  381. package/test/sap/ui/core/qunit/HTML.qunit.js +31 -31
  382. package/test/sap/ui/core/qunit/Lib.qunit.js +55 -2
  383. package/test/sap/ui/core/qunit/LocalBusyIndicator.qunit.js +22 -15
  384. package/test/sap/ui/core/qunit/ManagedObject.qunit.js +5 -3
  385. package/test/sap/ui/core/qunit/Object.qunit.js +4 -1
  386. package/test/sap/ui/core/qunit/ThemeManager.qunit.js +2 -2
  387. package/test/sap/ui/core/qunit/ThemeParameters.qunit.js +9 -3
  388. package/test/sap/ui/core/qunit/Theming.beforeBootstrap.qunit.js +13 -0
  389. package/test/sap/ui/core/qunit/Theming.qunit.js +229 -0
  390. package/test/sap/ui/core/qunit/analytics/AnalyticalTreeBindingAdapter.qunit.js +2 -7
  391. package/test/sap/ui/core/qunit/analytics/ODataModelAdapter.qunit.js +2 -7
  392. package/test/sap/ui/core/qunit/app/MessageListBinding.qunit.js +2 -7
  393. package/test/sap/ui/core/qunit/base/i18n/Formatting.qunit.html +24 -0
  394. package/test/sap/ui/core/qunit/base/i18n/Formatting.qunit.js +275 -0
  395. package/test/sap/ui/core/qunit/base/i18n/Localization.qunit.js +259 -0
  396. package/test/sap/ui/core/qunit/base/i18n/ResourceBundle.qunit.js +5 -6
  397. package/test/sap/ui/core/qunit/base/security/sanitizeHTML.qunit.js +17 -0
  398. package/test/sap/ui/core/qunit/bootstrap/BootstrapPreload.qunit.js +1 -2
  399. package/test/sap/ui/core/qunit/bootstrap/BootstrapWithCustomBootTask.beforeBootstrap.qunit.js +13 -12
  400. package/test/sap/ui/core/qunit/bootstrap/Configuration.qunit.js +388 -254
  401. package/test/sap/ui/core/qunit/bootstrap/ThemeVersion.qunit.js +19 -30
  402. package/test/sap/ui/core/qunit/component/Models.qunit.js +7 -28
  403. package/test/sap/ui/core/qunit/component/Models_unavoidablySync.qunit.js +8 -26
  404. package/test/sap/ui/core/qunit/component/testdata/async/lib2/library-preload.js +2 -2
  405. package/test/sap/ui/core/qunit/component/testdata/async/lib2/library-preload.json +1 -1
  406. package/test/sap/ui/core/qunit/component/testdata/async/lib2/library.js +2 -2
  407. package/test/sap/ui/core/qunit/component/testdata/async/lib3/library-preload.js +2 -2
  408. package/test/sap/ui/core/qunit/component/testdata/async/lib3/library-preload.json +1 -1
  409. package/test/sap/ui/core/qunit/component/testdata/async/lib3/library.js +2 -2
  410. package/test/sap/ui/core/qunit/component/testdata/async/lib4/library-preload.js +2 -2
  411. package/test/sap/ui/core/qunit/component/testdata/async/lib4/library-preload.json +1 -1
  412. package/test/sap/ui/core/qunit/component/testdata/async/lib4/library.js +2 -2
  413. package/test/sap/ui/core/qunit/component/testdata/async/manifestcomp/Component-preload.js +1 -1
  414. package/test/sap/ui/core/qunit/component/testdata/async/manifestcomp/Component.js +2 -2
  415. package/test/sap/ui/core/qunit/component/testdata/async/mycomp/Component-preload.js +1 -1
  416. package/test/sap/ui/core/qunit/component/testdata/async/mycomp/Component.js +2 -2
  417. package/test/sap/ui/core/qunit/component/testdata/async/mysubcomp/Component-preload.js +1 -1
  418. package/test/sap/ui/core/qunit/component/testdata/async/mysubcomp/Component.js +2 -3
  419. package/test/sap/ui/core/qunit/component/testdata/customizing/customer/ext/Component.js +0 -4
  420. package/test/sap/ui/core/qunit/component/testdata/customizing/customer/ext/sync/Component.js +2 -6
  421. package/test/sap/ui/core/qunit/component/testdata/customizing/customersub/Component.js +0 -4
  422. package/test/sap/ui/core/qunit/component/testdata/inherit/Component.js +2 -7
  423. package/test/sap/ui/core/qunit/component/testdata/inherit/parent/Component.js +2 -7
  424. package/test/sap/ui/core/qunit/component/testdata/inheritAsync/Component.js +2 -2
  425. package/test/sap/ui/core/qunit/component/testdata/inheritAsync/parentA/Component.js +2 -2
  426. package/test/sap/ui/core/qunit/component/testdata/inheritAsync/parentB/Component.js +2 -2
  427. package/test/sap/ui/core/qunit/component/testdata/inheritAsyncError/Component.js +2 -2
  428. package/test/sap/ui/core/qunit/component/testdata/inheritAsyncError/parentA/Component.js +2 -2
  429. package/test/sap/ui/core/qunit/component/testdata/inheritAsyncError/parentB/Component.js +2 -2
  430. package/test/sap/ui/core/qunit/component/testdata/other/Component.js +2 -7
  431. package/test/sap/ui/core/qunit/component/testdata/terminologies/Component.js +2 -2
  432. package/test/sap/ui/core/qunit/component/testdata/terminologies/component1/Component.js +2 -2
  433. package/test/sap/ui/core/qunit/component/testdata/terminologies/component2/Component.js +2 -2
  434. package/test/sap/ui/core/qunit/component/testdata/terminologies/component3/Component.js +2 -2
  435. package/test/sap/ui/core/qunit/component/testdata/terminologies/component5/Component.js +2 -2
  436. package/test/sap/ui/core/qunit/component/testdata/terminologies/reuse/Component.js +2 -3
  437. package/test/sap/ui/core/qunit/component/testdata/v1/Component.js +2 -7
  438. package/test/sap/ui/core/qunit/component/testdata/v1empty/Component.js +2 -7
  439. package/test/sap/ui/core/qunit/component/testdata/v1inline/Component.js +2 -5
  440. package/test/sap/ui/core/qunit/component/testdata/v1missing/Component.js +2 -7
  441. package/test/sap/ui/core/qunit/component/testdata/v2/Component.js +2 -5
  442. package/test/sap/ui/core/qunit/component/testdata/v2asyncRootView/Component.js +2 -5
  443. package/test/sap/ui/core/qunit/component/testdata/v2empty/Component.js +2 -9
  444. package/test/sap/ui/core/qunit/component/testdata/v2inline/Component.js +2 -5
  445. package/test/sap/ui/core/qunit/component/testdata/v2missing/Component.js +2 -9
  446. package/test/sap/ui/core/qunit/component/testdata/v2version/Component.js +2 -2
  447. package/test/sap/ui/core/qunit/dnd/DragDropInfo.qunit.js +1 -2
  448. package/test/sap/ui/core/qunit/generic/legacy/ControlMemoryLeaks.qunit.js +2 -0
  449. package/test/sap/ui/core/qunit/generic/legacy/DuplicateIdCheck.qunit.js +2 -0
  450. package/test/sap/ui/core/qunit/gherkin/dataTableUtils.qunit.js +2 -2
  451. package/test/sap/ui/core/qunit/i18n/Locale.qunit.js +0 -52
  452. package/test/sap/ui/core/qunit/i18n/LocaleData.qunit.js +1 -1
  453. package/test/sap/ui/core/qunit/i18n/UniversalDate.qunit.js +14 -24
  454. package/test/sap/ui/core/qunit/i18n/testsuite.i18n.qunit.js +18 -0
  455. package/test/sap/ui/core/qunit/internal/1RingModels.qunit.js +1 -0
  456. package/test/sap/ui/core/qunit/json/JSONListBinding.qunit.js +2 -7
  457. package/test/sap/ui/core/qunit/json/JSONPropertyBinding.qunit.js +7 -12
  458. package/test/sap/ui/core/qunit/json/JSONTwoWay.qunit.js +3 -8
  459. package/test/sap/ui/core/qunit/loader/fixture/amd-with-export-true/module1.js +2 -2
  460. package/test/sap/ui/core/qunit/messages/MessageMixin.qunit.js +2 -7
  461. package/test/sap/ui/core/qunit/messages/messagesUsage.qunit.js +1 -1
  462. package/test/sap/ui/core/qunit/model/Binding.qunit.js +36 -11
  463. package/test/sap/ui/core/qunit/model/ClientListBinding.qunit.js +2 -7
  464. package/test/sap/ui/core/qunit/model/ClientTreeBinding.qunit.js +2 -7
  465. package/test/sap/ui/core/qunit/model/CompositeDataState.qunit.js +2 -7
  466. package/test/sap/ui/core/qunit/model/Context.qunit.js +2 -7
  467. package/test/sap/ui/core/qunit/model/ContextBinding.qunit.js +2 -7
  468. package/test/sap/ui/core/qunit/model/ListBinding.qunit.js +63 -6
  469. package/test/sap/ui/core/qunit/model/Model.qunit.js +2 -7
  470. package/test/sap/ui/core/qunit/model/PropertyBinding.qunit.js +40 -0
  471. package/test/sap/ui/core/qunit/model/TreeBinding.qunit.js +2 -7
  472. package/test/sap/ui/core/qunit/model/TreeBindingAdapter.qunit.js +2 -7
  473. package/test/sap/ui/core/qunit/mvc/XMLView.qunit.js +9 -8
  474. package/test/sap/ui/core/qunit/mvc/extensions/Controllerextensions.qunit.js +4 -4
  475. package/test/sap/ui/core/qunit/mvc/extensions/Controllerextensions_legacy.qunit.js +4 -4
  476. package/test/sap/ui/core/qunit/odata/AnnotationParserNoFakeService.qunit.js +2 -7
  477. package/test/sap/ui/core/qunit/odata/ODataMessageParser.qunit.js +1 -1
  478. package/test/sap/ui/core/qunit/odata/ODataMessageParserNoFakeService.qunit.js +2 -8
  479. package/test/sap/ui/core/qunit/odata/ODataMetadataNoFakeService.qunit.js +1 -6
  480. package/test/sap/ui/core/qunit/odata/type/DateTimeBase.qunit.js +24 -0
  481. package/test/sap/ui/core/qunit/odata/v2/Context.qunit.js +2 -7
  482. package/test/sap/ui/core/qunit/odata/v2/ODataContextBindingNoFakeService.qunit.js +2 -7
  483. package/test/sap/ui/core/qunit/odata/v2/ODataListBindingNoFakeService.qunit.js +31 -17
  484. package/test/sap/ui/core/qunit/odata/v2/ODataModel.integration.qunit.js +28 -19
  485. package/test/sap/ui/core/qunit/odata/v2/ODataModelNoFakeService.qunit.js +70 -15
  486. package/test/sap/ui/core/qunit/odata/v2/ODataPropertyBindingNoFakeService.qunit.js +2 -7
  487. package/test/sap/ui/core/qunit/odata/v2/ODataTreeBindingFlatNoFakeService.qunit.js +4 -9
  488. package/test/sap/ui/core/qunit/odata/v2/ODataTreeBindingNoFakeService.qunit.js +2 -7
  489. package/test/sap/ui/core/qunit/odata/v2/_CreatedContextsCache.qunit.js +2 -7
  490. package/test/sap/ui/core/qunit/odata/v4/AnnotationHelper.qunit.js +1 -1
  491. package/test/sap/ui/core/qunit/odata/v4/Context.qunit.js +45 -17
  492. package/test/sap/ui/core/qunit/odata/v4/ODataBinding.qunit.js +152 -151
  493. package/test/sap/ui/core/qunit/odata/v4/ODataContextBinding.qunit.js +55 -27
  494. package/test/sap/ui/core/qunit/odata/v4/ODataListBinding.qunit.js +119 -4
  495. package/test/sap/ui/core/qunit/odata/v4/ODataMetaModel.qunit.js +3 -3
  496. package/test/sap/ui/core/qunit/odata/v4/ODataModel.integration.qunit.js +754 -195
  497. package/test/sap/ui/core/qunit/odata/v4/ODataModel.qunit.js +42 -53
  498. package/test/sap/ui/core/qunit/odata/v4/ODataParentBinding.qunit.js +283 -170
  499. package/test/sap/ui/core/qunit/odata/v4/ODataPropertyBinding.qunit.js +103 -78
  500. package/test/sap/ui/core/qunit/odata/v4/lib/_AggregationCache.qunit.js +3 -0
  501. package/test/sap/ui/core/qunit/odata/v4/lib/_Cache.qunit.js +87 -58
  502. package/test/sap/ui/core/qunit/odata/v4/lib/_Helper.qunit.js +3 -1
  503. package/test/sap/ui/core/qunit/odata/v4/lib/_Requestor.qunit.js +124 -22
  504. package/test/sap/ui/core/qunit/odata/v4/testsuite.odatav4.qunit.js +4 -0
  505. package/test/sap/ui/core/qunit/opa/_LogCollector.qunit.js +1 -1
  506. package/test/sap/ui/core/qunit/performance/trace/FESR.qunit.js +5 -0
  507. package/test/sap/ui/core/qunit/resource/ResourceModel.qunit.js +17 -37
  508. package/test/sap/ui/core/qunit/routing/HashChanger.qunit.js +1 -6
  509. package/test/sap/ui/core/qunit/routing/RouterHashChanger.qunit.js +1 -10
  510. package/test/sap/ui/core/qunit/routing/async/Router.qunit.js +1 -22
  511. package/test/sap/ui/core/qunit/routing/async/Target.qunit.js +1 -4
  512. package/test/sap/ui/core/qunit/rule/model/modelSupport.qunit.js +34 -1
  513. package/test/sap/ui/core/qunit/testdata/fastnavigation/view/FastNavigation.view.xml +2 -2
  514. package/test/sap/ui/core/qunit/testdata/libraries/resourcebundle/lib1/i18n.properties +1 -0
  515. package/test/sap/ui/core/qunit/testdata/libraries/resourcebundle/lib1/library.js +10 -0
  516. package/test/sap/ui/core/qunit/testdata/libraries/resourcebundle/lib1/manifest.json +10 -0
  517. package/test/sap/ui/core/qunit/testdata/libraries/resourcebundle/lib2/library.js +10 -0
  518. package/test/sap/ui/core/qunit/testdata/libraries/resourcebundle/lib2/messagebundle.properties +1 -0
  519. package/test/sap/ui/core/qunit/testsuites/testsuite.databinding.qunit.js +3 -0
  520. package/test/sap/ui/core/qunit/testsuites/testsuite.theming.qunit.js +29 -0
  521. package/test/sap/ui/core/qunit/types/DateFormatTimezones.qunit.js +397 -607
  522. package/test/sap/ui/core/qunit/types/SimpleType.qunit.js +16 -2
  523. package/test/sap/ui/core/qunit/types/Types.qunit.js +2 -37
  524. package/test/sap/ui/core/qunit/types/testsuite.types.qunit.js +1 -1
  525. package/test/sap/ui/core/qunit/util/SyncPromise.qunit.js +4 -1
  526. package/test/sap/ui/core/qunit/util/jQuery.sap.measure.qunit.js +16 -11
  527. package/test/sap/ui/core/qunit/xml/XMLListBinding.qunit.js +1 -3
  528. package/test/sap/ui/core/qunit/xml/XMLModel.qunit.js +4 -14
  529. package/test/sap/ui/core/qunit/xml/XMLPropertyBinding.qunit.js +7 -11
  530. package/test/sap/ui/core/qunit/xml/XMLTreeBinding.qunit.js +1 -1
  531. package/test/sap/ui/core/qunit/xml/XMLTwoWay.qunit.js +3 -7
  532. package/test/sap/ui/core/relnotes/changes-1.115.json +1 -37
  533. package/test/sap/ui/core/relnotes/changes-1.116.json +82 -0
  534. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/firstItem-contextMenu.ref.lnk +1 -1
  535. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/initial.ref.lnk +1 -1
  536. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/lastItem-contextMenu.ref.lnk +1 -1
  537. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/leftDownBtn-contextMenu.ref.lnk +1 -1
  538. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/myButtonSample-contextMenu.ref.lnk +1 -1
  539. package/test/sap/ui/core/visual/images/ContextMenuSupport/windows/1600x1200/chrome/horizon/ltr/cozy/rightDownBtn-contextMenu.ref.lnk +1 -1
  540. package/test/testsuite/js/samples.js +2 -0
  541. package/ui5.yaml +1 -1
@@ -24,6 +24,7 @@ sap.ui.define([
24
24
  "sap/ui/model/odata/OperationMode",
25
25
  "sap/ui/model/odata/v4/AnnotationHelper",
26
26
  "sap/ui/model/odata/v4/ODataListBinding",
27
+ "sap/ui/model/odata/v4/ODataMetaModel",
27
28
  "sap/ui/model/odata/v4/ODataModel",
28
29
  "sap/ui/model/odata/v4/ODataPropertyBinding",
29
30
  "sap/ui/model/odata/v4/ValueListType",
@@ -35,7 +36,8 @@ sap.ui.define([
35
36
  ], function (Log, uid, UriParameters, ColumnListItem, CustomListItem, FlexBox, _MessageStrip, Text,
36
37
  Device, EventProvider, SyncPromise, Configuration, Controller, View, ChangeReason, Filter,
37
38
  FilterOperator, FilterType, Sorter, OperationMode, AnnotationHelper, ODataListBinding,
38
- ODataModel, ODataPropertyBinding, ValueListType, _Helper, TestUtils, XMLHelper) {
39
+ ODataMetaModel, ODataModel, ODataPropertyBinding, ValueListType, _Helper, TestUtils,
40
+ XMLHelper) {
39
41
  /*eslint no-sparse-arrays: 0, "max-len": ["error", {"code": 100,
40
42
  "ignorePattern": "/sap/opu/odata4/|\" :$|\" : \\{$|\\{meta>"}], */
41
43
  "use strict";
@@ -2293,6 +2295,8 @@ sap.ui.define([
2293
2295
 
2294
2296
  //*********************************************************************************************
2295
2297
  // verify that error responses are processed correctly for change sets
2298
+ //
2299
+ // ...even if 1st change set fails and 2nd contains more than one request (BCP: 2380075648)
2296
2300
  QUnit.test("error response: $batch w/ change set (framework test)", function (assert) {
2297
2301
  var oModel = this.createSalesOrdersModel(),
2298
2302
  sView = '\
@@ -2308,12 +2312,13 @@ sap.ui.define([
2308
2312
  this.expectRequest("SalesOrderList?$skip=0&$top=100", {
2309
2313
  value : [
2310
2314
  {SalesOrderID : "1", Note : "Note 1"},
2311
- {SalesOrderID : "2", Note : "Note 2"}
2315
+ {SalesOrderID : "2", Note : "Note 2"},
2316
+ {SalesOrderID : "3", Note : "Note 3"}
2312
2317
  ]
2313
2318
  })
2314
2319
  .expectRequest("BusinessPartnerList('1')/CompanyName", {value : "SAP SE"})
2315
- .expectChange("id", ["1", "2"])
2316
- .expectChange("note", ["Note 1", "Note 2"])
2320
+ .expectChange("id", ["1", "2", "3"])
2321
+ .expectChange("note", ["Note 1", "Note 2", "Note 3"])
2317
2322
  .expectChange("name", "SAP SE");
2318
2323
 
2319
2324
  return this.createView(assert, sView, oModel).then(function () {
@@ -2329,10 +2334,12 @@ sap.ui.define([
2329
2334
  .withArgs("Failed to update path /SalesOrderList('1')/Note");
2330
2335
  that.oLogMock.expects("error")
2331
2336
  .withArgs("Failed to update path /SalesOrderList('2')/Note");
2337
+ that.oLogMock.expects("error")
2338
+ .withArgs("Failed to update path /SalesOrderList('3')/Note");
2332
2339
  that.oLogMock.expects("error")
2333
2340
  .withArgs("Failed to read path /BusinessPartnerList('1')/CompanyName");
2334
2341
 
2335
- that.expectChange("note", ["Note 1 changed", "Note 2 changed"])
2342
+ that.expectChange("note", ["Note 1 changed", "Note 2 changed", "Note 3 changed"])
2336
2343
  .expectRequest({
2337
2344
  changeSetNo : 1,
2338
2345
  method : "PATCH",
@@ -2340,11 +2347,17 @@ sap.ui.define([
2340
2347
  payload : {Note : "Note 1 changed"}
2341
2348
  }, oError)
2342
2349
  .expectRequest({
2343
- changeSetNo : 1,
2350
+ changeSetNo : 2,
2344
2351
  method : "PATCH",
2345
2352
  url : "SalesOrderList('2')",
2346
2353
  payload : {Note : "Note 2 changed"}
2347
2354
  }) // no response required
2355
+ .expectRequest({
2356
+ changeSetNo : 2,
2357
+ method : "PATCH",
2358
+ url : "SalesOrderList('3')",
2359
+ payload : {Note : "Note 3 changed"}
2360
+ }) // no response required
2348
2361
  .expectRequest("BusinessPartnerList('1')/CompanyName") // no response required
2349
2362
  .expectChange("name", null)
2350
2363
  .expectMessages([{
@@ -2361,7 +2374,9 @@ sap.ui.define([
2361
2374
  }]);
2362
2375
 
2363
2376
  aTableRows[0].getCells()[1].getBinding("value").setValue("Note 1 changed");
2377
+ oModel.submitBatch(oModel.getGroupId()); // close 1st change set
2364
2378
  aTableRows[1].getCells()[1].getBinding("value").setValue("Note 2 changed");
2379
+ aTableRows[2].getCells()[1].getBinding("value").setValue("Note 3 changed");
2365
2380
  that.oView.byId("name").getBinding("text").refresh();
2366
2381
 
2367
2382
  return that.waitForChanges(assert);
@@ -3579,19 +3594,24 @@ sap.ui.define([
3579
3594
  // Scenario: ODLB, late property. See that it is requested only once, even when bound twice. See
3580
3595
  // that it is updated via requestSideEffects called at the parent binding (all visible rows).
3581
3596
  // JIRA: CPOUI5UISERVICESV3-1878
3582
- // JIRA: CPOUI5ODATAV4-23 see that a late property for a nested entity (within $expand) is
3583
- // fetched
3584
- // JIRA: CPOUI5ODATAV4-27 see that two late property requests are merged
3585
- // BCP: 2070470932: see that sap-client and system query options are handled properly
3586
- // Test ODLB#getCount
3587
- // JIRA: CPOUI5ODATAV4-958
3588
- // JIRA: CPOUI5ODATAV4-1671: See that dataRequested/dataReceived events are fired for late
3589
- // property requests
3590
- // JIRA: CPOUI5ODATAV4-1746 See that every GET request for late property requests is causing
3591
- // dataRequested/dataReceived events. The additional GET request for late properties
3592
- // is achieved by requesting an additional entity with the path
3593
- // "TEAMS('1')/TEAM_2_EMPLOYEES('3')". The path from the GET request is attached to the event
3594
- // parameter, no matter whether the request failed or succeeded.
3597
+ //
3598
+ // See that a late property for a nested entity (within $expand) is fetched
3599
+ // JIRA: CPOUI5ODATAV4-23
3600
+ //
3601
+ // See that two late property requests are merged (JIRA: CPOUI5ODATAV4-27)
3602
+ // See that sap-client and system query options are handled properly (BCP: 2070470932)
3603
+ // Test ODLB#getCount (JIRA: CPOUI5ODATAV4-958)
3604
+ //
3605
+ // See that dataRequested/dataReceived events are fired for late property requests
3606
+ // JIRA: CPOUI5ODATAV4-1671
3607
+ //
3608
+ // See that every GET request for late property requests is causing dataRequested/dataReceived
3609
+ // events. The additional GET request for late properties is achieved by requesting an
3610
+ // additional item with ItemPosition "20". The path from the GET request is attached to the
3611
+ // event parameter, no matter whether the request failed or succeeded.
3612
+ // JIRA: CPOUI5ODATAV4-1746
3613
+ //
3614
+ // Rewritten to use SalesOrder instead of TEAM (JIRA: CPOUI5ODATAV4-2172)
3595
3615
  QUnit.test("ODLB: late property", function (assert) {
3596
3616
  var bChange = false,
3597
3617
  iDataReceived = 0,
@@ -3601,66 +3621,70 @@ sap.ui.define([
3601
3621
  oRowContext,
3602
3622
  oTable,
3603
3623
  sView = '\
3604
- <FlexBox id="form" binding="{/TEAMS(\'1\')}">\
3624
+ <FlexBox id="form" binding="{/SalesOrderList(\'1\')}">\
3605
3625
  <Table id="table" growing="true" growingThreshold="2"\
3606
- items="{path : \'TEAM_2_EMPLOYEES\', parameters : {$$ownRequest : true,\
3607
- $search : \'foo\', $select : \'__CT__FAKE__Message/__FAKE__Messages\'}}">\
3608
- <Text id="name" text="{Name}"/>\
3609
- <Text id="manager" text="{EMPLOYEE_2_MANAGER/ID}"/>\
3626
+ items="{path : \'SO_2_SOITEM\', \
3627
+ parameters : {$$ownRequest : true, $search : \'foo\', $select : \'Messages\'}}">\
3628
+ <Text id="note" text="{Note}"/>\
3629
+ <Text id="scheduleKey" text="{SOITEM_2_SCHDL/ScheduleKey}"/>\
3610
3630
  </Table>\
3611
3631
  </FlexBox>\
3612
- <Input id="age1" value="{AGE}"/>\
3613
- <Text id="age2" text="{AGE}"/>\
3614
- <Input id="team" value="{EMPLOYEE_2_TEAM/TEAM_2_MANAGER/TEAM_ID}"/>\
3615
- <Input id="budget" value="{EMPLOYEE_2_TEAM/Budget}"/>',
3632
+ <Input id="unit1" value="{QuantityUnit}"/>\
3633
+ <Text id="unit2" text="{QuantityUnit}"/>\
3634
+ <Input id="bp" value="{SOITEM_2_PRODUCT/PRODUCT_2_BP/CompanyName}"/>',
3616
3635
  that = this;
3617
3636
 
3618
- oModel = this.createModel(sTeaBusi + "?sap-client=123", {autoExpandSelect : true}, {
3619
- "/sap/opu/odata4/IWBEP/TEA/default/IWBEP/TEA_BUSI/0001/$metadata?sap-client=123"
3620
- : {source : "odata/v4/data/metadata.xml"}
3637
+ oModel = this.createModel(sSalesOrderService + "?sap-client=123", {
3638
+ autoExpandSelect : true
3639
+ }, {
3640
+ "/sap/opu/odata4/sap/zui5_testv4/default/sap/zui5_epm_sample/0002/$metadata?sap-client=123"
3641
+ : {source : "odata/v4/data/metadata_zui5_epm_sample.xml"}
3621
3642
  });
3622
3643
 
3623
- this.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES?sap-client=123&$search=foo"
3624
- + "&$select=ID,Name,__CT__FAKE__Message/__FAKE__Messages"
3625
- + "&$expand=EMPLOYEE_2_MANAGER($select=ID)&$skip=0&$top=2", {
3644
+ this.expectRequest("SalesOrderList('1')/SO_2_SOITEM?sap-client=123&$search=foo"
3645
+ + "&$select=ItemPosition,Messages,Note,SalesOrderID"
3646
+ + "&$expand=SOITEM_2_SCHDL($select=ScheduleKey)&$skip=0&$top=2", {
3626
3647
  value : [{
3627
3648
  "@odata.etag" : "etag0",
3628
- ID : "2",
3629
- Name : "Frederic Fall",
3630
- EMPLOYEE_2_MANAGER : {ID : "5"}
3649
+ ItemPosition : "10",
3650
+ Messages : [],
3651
+ Note : "Note #10",
3652
+ SalesOrderID : "1",
3653
+ SOITEM_2_SCHDL : {ScheduleKey : "Key #10"}
3631
3654
  }, {
3632
3655
  "@odata.etag" : "etag0",
3633
- ID : "3",
3634
- Name : "Jonathan Smith",
3635
- EMPLOYEE_2_MANAGER : {ID : "5"}
3656
+ ItemPosition : "20",
3657
+ Messages : [],
3658
+ Note : "Note #20",
3659
+ SalesOrderID : "1",
3660
+ SOITEM_2_SCHDL : {ScheduleKey : "Key #20"}
3636
3661
  }]
3637
3662
  })
3638
- .expectChange("name", ["Frederic Fall", "Jonathan Smith"])
3639
- .expectChange("manager", ["5", "5"])
3640
- .expectChange("age1")
3641
- .expectChange("age2")
3642
- .expectChange("team")
3643
- .expectChange("budget");
3663
+ .expectChange("note", ["Note #10", "Note #20"])
3664
+ .expectChange("scheduleKey", ["Key #10", "Key #20"])
3665
+ .expectChange("unit1")
3666
+ .expectChange("unit2")
3667
+ .expectChange("bp");
3644
3668
 
3645
3669
  return this.createView(assert, sView, oModel).then(function () {
3646
- var oTeam = that.oView.byId("team");
3670
+ var oBusinessPartner = that.oView.byId("bp");
3647
3671
 
3648
3672
  oTable = that.oView.byId("table");
3649
- oTeam.getBinding("value").attachEventOnce("change", function (oEvent) {
3673
+ oBusinessPartner.getBinding("value").attachEventOnce("change", function (oEvent) {
3650
3674
  bChange = true;
3651
- assert.strictEqual(oEvent.getSource().getValue(), "1");
3652
- assert.strictEqual(oTeam.getValue(), "1");
3675
+ assert.strictEqual(oEvent.getSource().getValue(), "ACM");
3676
+ assert.strictEqual(oBusinessPartner.getValue(), "ACM");
3653
3677
  });
3654
3678
  oModel.attachDataRequested(function (oEvent) {
3655
3679
  sPath = oEvent.getParameter("path");
3656
3680
 
3657
3681
  iDataRequested += 1;
3658
3682
  if (iDataRequested === 1) {
3659
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('2')");
3683
+ assert.strictEqual(sPath,
3684
+ "/SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')");
3660
3685
  } else if (iDataRequested === 2) {
3661
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('3')");
3662
- } else if (iDataRequested === 3) {
3663
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('2')/EMPLOYEE_2_TEAM");
3686
+ assert.strictEqual(sPath,
3687
+ "/SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')");
3664
3688
  }
3665
3689
  }).attachDataReceived(function (oEvent) {
3666
3690
  sPath = oEvent.getParameter("path");
@@ -3669,13 +3693,13 @@ sap.ui.define([
3669
3693
  assert.deepEqual(oEvent.getParameter("data"), {});
3670
3694
 
3671
3695
  if (iDataReceived === 1) {
3672
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('3')");
3696
+ assert.strictEqual(sPath,
3697
+ "/SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')");
3673
3698
  assert.strictEqual(bChange, false, "change event not yet fired");
3674
3699
  } else if (iDataReceived === 2) {
3675
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('2')");
3700
+ assert.strictEqual(sPath,
3701
+ "/SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')");
3676
3702
  assert.strictEqual(bChange, true, "fired after change event");
3677
- } else if (iDataReceived === 3) {
3678
- assert.strictEqual(sPath, "/TEAMS('1')/TEAM_2_EMPLOYEES('2')/EMPLOYEE_2_TEAM");
3679
3703
  }
3680
3704
  });
3681
3705
 
@@ -3685,53 +3709,55 @@ sap.ui.define([
3685
3709
 
3686
3710
  that.expectRequest({
3687
3711
  batchNo : 2,
3688
- url : "TEAMS('1')/TEAM_2_EMPLOYEES('2')?sap-client=123"
3689
- + "&$select=AGE&$expand=EMPLOYEE_2_TEAM($select=Team_Id;"
3690
- + "$expand=TEAM_2_MANAGER($select=ID,TEAM_ID))"
3712
+ url : "SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')"
3713
+ + "?sap-client=123"
3714
+ + "&$select=QuantityUnit&$expand=SOITEM_2_PRODUCT($select=ProductID;"
3715
+ + "$expand=PRODUCT_2_BP($select=BusinessPartnerID,CompanyName))"
3691
3716
  }, {
3692
3717
  "@odata.etag" : "etag0",
3693
- AGE : 42,
3694
- EMPLOYEE_2_TEAM : {
3718
+ QuantityUnit : "kg",
3719
+ SOITEM_2_PRODUCT : {
3695
3720
  "@odata.etag" : "etag1",
3696
- Team_Id : "1",
3697
- TEAM_2_MANAGER : {
3721
+ ProductID : "3",
3722
+ PRODUCT_2_BP : {
3698
3723
  "@odata.etag" : "ETag",
3699
- ID : "5",
3700
- TEAM_ID : "1"
3724
+ BusinessPartnerID : "4",
3725
+ CompanyName : "ACM"
3701
3726
  }
3702
3727
  }
3703
3728
  })
3704
3729
  // the additional late property request
3705
3730
  .expectRequest({
3706
3731
  batchNo : 2,
3707
- url : "TEAMS('1')/TEAM_2_EMPLOYEES('3')?sap-client=123"
3708
- + "&$select=EMPLOYEE_2_TEAM&$expand=EMPLOYEE_2_TEAM($select=Team_Id;"
3709
- + "$expand=TEAM_2_MANAGER($select=ID,TEAM_ID))"
3732
+ url : "SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')"
3733
+ + "?sap-client=123"
3734
+ + "&$select=SOITEM_2_PRODUCT&$expand=SOITEM_2_PRODUCT($select=ProductID;"
3735
+ + "$expand=PRODUCT_2_BP($select=BusinessPartnerID,CompanyName))"
3710
3736
  }, {
3711
3737
  "@odata.etag" : "etag0",
3712
- EMPLOYEE_2_TEAM : {
3738
+ SOITEM_2_PRODUCT : {
3713
3739
  "@odata.etag" : "etag1",
3714
- Team_Id : "1",
3715
- TEAM_2_MANAGER : {
3740
+ ProductID : "3",
3741
+ PRODUCT_2_BP : {
3716
3742
  "@odata.etag" : "ETag",
3717
- ID : "5",
3718
- TEAM_ID : "1"
3743
+ BusinessPartnerID : "4",
3744
+ CompanyName : "ACM"
3719
3745
  }
3720
3746
  }
3721
3747
  })
3722
- .expectChange("age1", "42")
3723
- .expectChange("team", "1");
3748
+ .expectChange("unit1", "kg")
3749
+ .expectChange("bp", "ACM");
3724
3750
 
3725
- // code under test - AGE and Team_Id are requested
3751
+ // code under test - QuantityUnit and CompanyName are requested
3726
3752
  oRowContext = oTable.getItems()[0].getBindingContext();
3727
- that.oView.byId("age1").setBindingContext(oRowContext);
3728
- that.oView.byId("team").setBindingContext(oRowContext);
3753
+ that.oView.byId("unit1").setBindingContext(oRowContext);
3754
+ that.oView.byId("bp").setBindingContext(oRowContext);
3729
3755
 
3730
3756
  return Promise.all([
3731
3757
  // the additional late property request for a *different* row
3732
3758
  // JIRA: CPOUI5ODATAV4-1746
3733
3759
  oTable.getItems()[1].getBindingContext()
3734
- .requestProperty("EMPLOYEE_2_TEAM/TEAM_2_MANAGER/TEAM_ID"),
3760
+ .requestProperty("SOITEM_2_PRODUCT/PRODUCT_2_BP/CompanyName"),
3735
3761
  that.waitForChanges(assert)
3736
3762
  ]);
3737
3763
  }).then(function () {
@@ -3739,164 +3765,160 @@ sap.ui.define([
3739
3765
  assert.strictEqual(iDataReceived, 2);
3740
3766
 
3741
3767
  // BCP 1980517597
3742
- that.expectChange("age1", "18")
3768
+ that.expectChange("unit1", "t")
3743
3769
  .expectRequest({
3744
3770
  method : "PATCH",
3745
3771
  headers : {"If-Match" : "etag0"},
3746
- url : "EMPLOYEES('2')?sap-client=123",
3747
- payload : {AGE : 18}
3772
+ url : "SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')"
3773
+ + "?sap-client=123",
3774
+ payload : {QuantityUnit : "t"}
3748
3775
  }, {
3749
3776
  "@odata.etag" : "etag23",
3750
3777
  AGE : 18,
3751
- __CT__FAKE__Message : {
3752
- __FAKE__Messages : [{
3753
- code : "1",
3754
- message : "That is very young",
3755
- numericSeverity : 3,
3756
- target : "AGE",
3757
- transition : false
3758
- }]
3759
- }
3778
+ Messages : [{
3779
+ code : "1",
3780
+ message : "Are you sure?",
3781
+ numericSeverity : 3,
3782
+ target : "QuantityUnit",
3783
+ transition : false
3784
+ }]
3760
3785
  })
3761
3786
  .expectMessages([{
3762
3787
  code : "1",
3763
- message : "That is very young",
3764
- target : "/TEAMS('1')/TEAM_2_EMPLOYEES('2')/AGE",
3788
+ message : "Are you sure?",
3789
+ target : "/SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='10')"
3790
+ + "/QuantityUnit",
3765
3791
  type : "Warning"
3766
3792
  }]);
3767
3793
 
3768
3794
  // code under test
3769
- that.oView.byId("age1").getBinding("value").setValue(18);
3795
+ that.oView.byId("unit1").getBinding("value").setValue("t");
3770
3796
 
3771
3797
  return that.waitForChanges(assert);
3772
3798
  }).then(function () {
3773
- return that.checkValueState(assert, "age1", "Warning", "That is very young");
3799
+ return that.checkValueState(assert, "unit1", "Warning", "Are you sure?");
3774
3800
  }).then(function () {
3775
- that.expectChange("team", "changed")
3801
+ that.expectChange("bp", "changed")
3776
3802
  .expectRequest({
3777
3803
  method : "PATCH",
3778
3804
  headers : {"If-Match" : "ETag"},
3779
- url : "MANAGERS('5')?sap-client=123",
3780
- payload : {TEAM_ID : "changed"}
3805
+ url : "BusinessPartnerList('4')?sap-client=123",
3806
+ payload : {CompanyName : "changed"}
3781
3807
  });
3782
3808
 
3783
3809
  // code under test
3784
- that.oView.byId("team").getBinding("value").setValue("changed");
3810
+ that.oView.byId("bp").getBinding("value").setValue("changed");
3785
3811
 
3786
3812
  return that.waitForChanges(assert);
3787
3813
  }).then(function () {
3788
3814
  assert.strictEqual(iDataRequested, 2);
3789
3815
  assert.strictEqual(iDataReceived, 2);
3790
3816
 
3791
- that.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES('2')/EMPLOYEE_2_TEAM?sap-client=123"
3792
- + "&$select=Budget,Team_Id", {
3793
- "@odata.etag" : "etag1",
3794
- Budget : "12.45",
3795
- Team_Id : "1"
3796
- })
3797
- .expectChange("budget", "12.45");
3798
-
3799
- // code under test - now the team is in the cache and only the budget is missing
3800
- that.oView.byId("budget").setBindingContext(oRowContext);
3817
+ that.expectChange("unit2", "t");
3801
3818
 
3802
- return that.waitForChanges(assert);
3803
- }).then(function () {
3804
- assert.strictEqual(iDataRequested, 3);
3805
- assert.strictEqual(iDataReceived, 3);
3806
-
3807
- that.expectChange("age2", "18");
3808
-
3809
- // code under test - AGE is cached now
3810
- that.oView.byId("age2").setBindingContext(oRowContext);
3819
+ // code under test - QuantityUnit is cached now
3820
+ that.oView.byId("unit2").setBindingContext(oRowContext);
3811
3821
 
3812
3822
  return that.waitForChanges(assert);
3813
3823
  }).then(function () {
3814
- that.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES?sap-client=123&$search=foo"
3815
- + "&$select=ID,Name,__CT__FAKE__Message/__FAKE__Messages"
3816
- + "&$expand=EMPLOYEE_2_MANAGER($select=ID)&$skip=2&$top=2", {
3817
- value : [
3818
- {ID : "4", Name : "Peter Burke", EMPLOYEE_2_MANAGER : {ID : "5"}}
3819
- ]
3824
+ that.expectRequest("SalesOrderList('1')/SO_2_SOITEM?sap-client=123&$search=foo"
3825
+ + "&$select=ItemPosition,Messages,Note,SalesOrderID"
3826
+ + "&$expand=SOITEM_2_SCHDL($select=ScheduleKey)&$skip=2&$top=2", {
3827
+ value : [{
3828
+ ItemPosition : "30",
3829
+ Messages : [],
3830
+ Note : "Note #30",
3831
+ SalesOrderID : "1",
3832
+ SOITEM_2_SCHDL : {ScheduleKey : "Key #30"}
3833
+ }]
3820
3834
  })
3821
- .expectChange("name", [,, "Peter Burke"])
3822
- .expectChange("manager", [,, "5"]);
3835
+ .expectChange("note", [,, "Note #30"])
3836
+ .expectChange("scheduleKey", [,, "Key #30"]);
3823
3837
 
3824
- // code under test - AGE must not be requested when paging
3838
+ // code under test - QuantityUnit must not be requested when paging
3825
3839
  oTable.requestItems();
3826
3840
 
3827
3841
  return that.waitForChanges(assert);
3828
3842
  }).then(function () {
3829
- assert.strictEqual(iDataRequested, 4, "bubbled up from the binding");
3830
- assert.strictEqual(iDataReceived, 4, "bubbled up from the binding");
3843
+ assert.strictEqual(iDataRequested, 3, "bubbled up from the binding");
3844
+ assert.strictEqual(iDataReceived, 3, "bubbled up from the binding");
3831
3845
 
3832
- that.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES?sap-client=123&$select=AGE,ID,Name"
3833
- + "&$filter=ID eq '2' or ID eq '3' or ID eq '4'&$top=3", {
3846
+ that.expectRequest("SalesOrderList('1')/SO_2_SOITEM?sap-client=123"
3847
+ + "&$select=ItemPosition,Note,QuantityUnit,SalesOrderID"
3848
+ + "&$filter=SalesOrderID eq '1' and ItemPosition eq '10' or SalesOrderID eq '1'"
3849
+ + " and ItemPosition eq '20' or SalesOrderID eq '1' and ItemPosition eq '30'"
3850
+ + "&$top=3", {
3834
3851
  value : [
3835
- {AGE : 43, ID : "2", Name : "Frederic Fall *"},
3836
- {AGE : 29, ID : "3", Name : "Jonathan Smith *"},
3837
- {AGE : 0, ID : "4", Name : "Peter Burke *"}
3852
+ {ItemPosition : "10", Note : "#1", QuantityUnit : "g", SalesOrderID : "1"},
3853
+ {ItemPosition : "20", Note : "#2", QuantityUnit : "dz", SalesOrderID : "1"},
3854
+ {ItemPosition : "30", Note : "#3", QuantityUnit : "g", SalesOrderID : "1"}
3838
3855
  ]
3839
3856
  })
3840
- .expectChange("age1", "43")
3841
- .expectChange("age2", "43")
3842
- .expectChange("name", ["Frederic Fall *", "Jonathan Smith *", "Peter Burke *"]);
3857
+ .expectChange("unit1", "g")
3858
+ .expectChange("unit2", "g")
3859
+ .expectChange("note", ["#1", "#2", "#3"]);
3843
3860
 
3844
- // see that requestSideEffects updates AGE, too
3861
+ // see that requestSideEffects updates QuantityUnit, too
3845
3862
  return Promise.all([
3846
- oTable.getBinding("items").getHeaderContext().requestSideEffects(["AGE", "Name"]),
3863
+ oTable.getBinding("items").getHeaderContext()
3864
+ .requestSideEffects(["Note", "QuantityUnit"]),
3847
3865
  that.waitForChanges(assert)
3848
3866
  ]);
3849
3867
  }).then(function () {
3850
- assert.strictEqual(iDataRequested, 4);
3851
- assert.strictEqual(iDataReceived, 4);
3868
+ assert.strictEqual(iDataRequested, 3);
3869
+ assert.strictEqual(iDataReceived, 3);
3852
3870
 
3853
- that.expectChange("age2", "29");
3871
+ that.expectChange("unit2", "dz");
3854
3872
 
3855
3873
  // change one Text to the second row - must be cached from requestSideEffects
3856
3874
  oRowContext = oTable.getItems()[1].getBindingContext();
3857
- that.oView.byId("age2").setBindingContext(oRowContext);
3875
+ that.oView.byId("unit2").setBindingContext(oRowContext);
3858
3876
 
3859
3877
  return that.waitForChanges(assert);
3860
3878
  }).then(function () {
3861
- assert.strictEqual(iDataRequested, 4);
3862
- assert.strictEqual(iDataReceived, 4);
3879
+ assert.strictEqual(iDataRequested, 3);
3880
+ assert.strictEqual(iDataReceived, 3);
3863
3881
 
3864
- that.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES?sap-client=123&$select=AGE,ID,Name"
3865
- + "&$filter=ID eq '2' or ID eq '3' or ID eq '4'&$top=3", {
3882
+ that.expectRequest("SalesOrderList('1')/SO_2_SOITEM?sap-client=123"
3883
+ + "&$select=ItemPosition,Note,QuantityUnit,SalesOrderID"
3884
+ + "&$filter=SalesOrderID eq '1' and ItemPosition eq '10' or SalesOrderID eq '1'"
3885
+ + " and ItemPosition eq '20' or SalesOrderID eq '1' and ItemPosition eq '30'"
3886
+ + "&$top=3", {
3866
3887
  value : [
3867
- {AGE : 44, ID : "2", Name : "Frederic Fall **"},
3868
- {AGE : 30, ID : "3", Name : "Jonathan Smith **"},
3869
- {AGE : -1, ID : "4", Name : "Peter Burke **"}
3888
+ {ItemPosition : "10", Note : "$1", QuantityUnit : "ou", SalesOrderID : "1"},
3889
+ {ItemPosition : "20", Note : "$2", QuantityUnit : "t", SalesOrderID : "1"},
3890
+ {ItemPosition : "30", Note : "$3", QuantityUnit : "?", SalesOrderID : "1"}
3870
3891
  ]
3871
3892
  })
3872
- .expectChange("age1", "44")
3873
- .expectChange("age2", "30")
3874
- .expectChange("name", ["Frederic Fall **", "Jonathan Smith **", "Peter Burke **"]);
3893
+ .expectChange("unit1", "ou")
3894
+ .expectChange("unit2", "t")
3895
+ .expectChange("note", ["$1", "$2", "$3"]);
3875
3896
 
3876
3897
  return Promise.all([
3877
3898
  // code under test: requestSideEffects on ODCB w/o data
3878
3899
  that.oView.byId("form").getBindingContext().requestSideEffects([
3879
- {$PropertyPath : "TEAM_2_EMPLOYEES/AGE"},
3880
- {$PropertyPath : "TEAM_2_EMPLOYEES/Name"}
3900
+ {$PropertyPath : "SO_2_SOITEM/QuantityUnit"},
3901
+ {$PropertyPath : "SO_2_SOITEM/Note"}
3881
3902
  ]),
3882
3903
  that.waitForChanges(assert)
3883
3904
  ]);
3884
3905
  }).then(function () {
3885
- assert.strictEqual(iDataRequested, 4);
3886
- assert.strictEqual(iDataReceived, 4);
3906
+ assert.strictEqual(iDataRequested, 3);
3907
+ assert.strictEqual(iDataReceived, 3);
3887
3908
 
3888
- that.expectRequest("TEAMS('1')/TEAM_2_EMPLOYEES('3')?sap-client=123&$select=TEAM_ID",
3889
- {"@odata.etag" : "etag0", TEAM_ID : "1"});
3909
+ that.expectRequest("SalesOrderList('1')/SO_2_SOITEM(SalesOrderID='1',ItemPosition='20')"
3910
+ + "?sap-client=123&$select=CurrencyCode",
3911
+ {"@odata.etag" : "etag0", CurrencyCode : "USD"});
3890
3912
 
3891
3913
  return Promise.all([
3892
- oRowContext.requestProperty("TEAM_ID").then(function (sTeamId) {
3893
- assert.strictEqual(sTeamId, "1");
3914
+ oRowContext.requestProperty("CurrencyCode").then(function (sCurrencyCode) {
3915
+ assert.strictEqual(sCurrencyCode, "USD");
3894
3916
  }),
3895
3917
  that.waitForChanges(assert)
3896
3918
  ]);
3897
3919
  }).then(function () {
3898
- assert.strictEqual(iDataRequested, 5);
3899
- assert.strictEqual(iDataReceived, 5);
3920
+ assert.strictEqual(iDataRequested, 4);
3921
+ assert.strictEqual(iDataReceived, 4);
3900
3922
  });
3901
3923
  });
3902
3924
 
@@ -7289,17 +7311,17 @@ sap.ui.define([
7289
7311
  {reason : "refresh"}],
7290
7312
  ["ContextBinding: /SalesOrderList('0500000001')", "change",
7291
7313
  {reason : "refresh"}],
7292
- ["ContextBinding: /SalesOrderList('0500000001')", "dataRequested"],
7293
7314
  ["ListBinding: /SalesOrderList('0500000001')|SO_2_SOITEM", "dataRequested"],
7315
+ ["ContextBinding: /SalesOrderList('0500000001')", "dataRequested"],
7294
7316
  ["ContextBinding: /SalesOrderList('0500000001')", "dataReceived", {data : {}}],
7295
7317
  ["ListBinding: /SalesOrderList('0500000001')|SO_2_SOITEM", "change",
7296
7318
  {reason : "change"}],
7297
7319
  ["ListBinding: /SalesOrderList('0500000001')|SO_2_SOITEM", "dataReceived",
7298
7320
  {data : {}}],
7299
- ["PropertyBinding: /SalesOrderList('0500000001')|Note", "change",
7300
- {reason : "refresh"}],
7301
7321
  ["PropertyBinding: /SalesOrderList('0500000001')/SO_2_SOITEM|$count", "change",
7302
7322
  {reason : "change"}],
7323
+ ["PropertyBinding: /SalesOrderList('0500000001')|Note", "change",
7324
+ {reason : "refresh"}],
7303
7325
  ["PropertyBinding: /SalesOrderList('0500000001')/SO_2_SOITEM/2[2]|ItemPosition",
7304
7326
  "change", {reason : "change"}]
7305
7327
  ])
@@ -7331,7 +7353,7 @@ sap.ui.define([
7331
7353
  // BCP: 2270183841
7332
7354
  QUnit.test("BCP: 2270183841 - improve performance of ODLB#resume", function (assert) {
7333
7355
  var oModel = this.createTeaBusiModel({autoExpandSelect : true}),
7334
- fnSpy = sinon.spy(ODataPropertyBinding.prototype, "resumeInternal"),
7356
+ fnSpy = this.spy(ODataPropertyBinding.prototype, "resumeInternal"),
7335
7357
  sView = '\
7336
7358
  <t:Table id="table" rows="{/EMPLOYEES}" threshold="0" visibleRowCount="3">\
7337
7359
  <Text id="id" text="{ID}"/>\
@@ -7377,6 +7399,167 @@ sap.ui.define([
7377
7399
  });
7378
7400
  });
7379
7401
 
7402
+ //*********************************************************************************************
7403
+ // Scenario: A table shows a number of cells and then we scroll down. See that property bindings
7404
+ // do not recompute "static" information in vain.
7405
+ // BCP: 156484 / 2023 (002075129500001564842023)
7406
+ QUnit.test("BCP: 156484 / 2023 - improve performance of ODPrB#setContext", function (assert) {
7407
+ var fnSpy_ODMM_fetchUI5Type = this.spy(ODataMetaModel.prototype, "fetchUI5Type"),
7408
+ fnSpy_ODMM_getReducedPath = this.spy(ODataMetaModel.prototype, "getReducedPath"),
7409
+ fnSpy_ODLB_doFetchOrGetQueryOptions
7410
+ = this.spy(ODataListBinding.prototype, "doFetchOrGetQueryOptions"),
7411
+ oModel = this.createTeaBusiModel({autoExpandSelect : true}),
7412
+ sView = '\
7413
+ <t:Table id="table" rows="{/EMPLOYEES}" visibleRowCount="3">\
7414
+ <Text id="id" text="{ID}"/>\
7415
+ <Text id="name" text="{Name}"/>\
7416
+ <Text id="age" text="{path:\'AGE\',type:\'sap.ui.model.odata.type.Int16\'\
7417
+ ,formatOptions:{\'minIntegerDigits\':3}}"/>\
7418
+ </t:Table>',
7419
+ that = this;
7420
+
7421
+ this.expectRequest("EMPLOYEES?$select=AGE,ID,Name&$skip=0&$top=103", {
7422
+ value : [{
7423
+ AGE : 70,
7424
+ ID : "0",
7425
+ Name : "Frederic Fall"
7426
+ }, {
7427
+ AGE : 60,
7428
+ ID : "1",
7429
+ Name : "Jonathan Smith"
7430
+ }, {
7431
+ AGE : 50,
7432
+ ID : "2",
7433
+ Name : "Peter Burke"
7434
+ }, {
7435
+ AGE : 40,
7436
+ ID : "3",
7437
+ Name : "Carla Blue"
7438
+ }, {
7439
+ AGE : 30,
7440
+ ID : "4",
7441
+ Name : "John Field"
7442
+ }, {
7443
+ AGE : 20,
7444
+ ID : "5",
7445
+ Name : "Susan Bay"
7446
+ }]
7447
+ })
7448
+ .expectChange("id", ["0", "1", "2"])
7449
+ .expectChange("name", ["Frederic Fall", "Jonathan Smith", "Peter Burke"])
7450
+ .expectChange("age", ["070", "060", "050"])
7451
+ .expectChange("lastModifiedAt", []);
7452
+
7453
+ return this.createView(assert, sView, oModel).then(function () {
7454
+ assert.strictEqual(fnSpy_ODMM_fetchUI5Type.callCount, 6, // was: 12
7455
+ "initial #fetchUI5Type");
7456
+ assert.strictEqual(fnSpy_ODMM_getReducedPath.callCount, 3); // was: 12
7457
+ assert.strictEqual(fnSpy_ODLB_doFetchOrGetQueryOptions.callCount, 4); // was: 13
7458
+
7459
+ that.expectChange("id", [, "1", "2", "3"])
7460
+ .expectChange("name", [, "Jonathan Smith", "Peter Burke", "Carla Blue"])
7461
+ .expectChange("age", [, "060", "050", "040"]);
7462
+
7463
+ that.oView.byId("table").setFirstVisibleRow(1);
7464
+
7465
+ return that.waitForChanges(assert, "scroll down 1x");
7466
+ }).then(function () {
7467
+ assert.strictEqual(fnSpy_ODMM_fetchUI5Type.callCount, 6, "no more #fetchUI5Type");
7468
+ assert.strictEqual(fnSpy_ODMM_getReducedPath.callCount, 3); // was: 21
7469
+ assert.strictEqual(fnSpy_ODLB_doFetchOrGetQueryOptions.callCount, 4); // was: 22
7470
+
7471
+ that.expectChange("id", [,,, "3", "4", "5"])
7472
+ .expectChange("name", [,,, "Carla Blue", "John Field", "Susan Bay"])
7473
+ .expectChange("age", [,,, "040", "030", "020"]);
7474
+
7475
+ that.oView.byId("table").setFirstVisibleRow(3);
7476
+
7477
+ return that.waitForChanges(assert, "scroll down 2x");
7478
+ }).then(function () {
7479
+ assert.strictEqual(fnSpy_ODMM_fetchUI5Type.callCount, 6, "no more #fetchUI5Type");
7480
+ assert.strictEqual(fnSpy_ODMM_getReducedPath.callCount, 3); // was: 31
7481
+ assert.strictEqual(fnSpy_ODLB_doFetchOrGetQueryOptions.callCount, 4); // was: 30
7482
+ });
7483
+ });
7484
+
7485
+ //*********************************************************************************************
7486
+ // Scenario: A field shows a property where the exact type depends on the parent entity.
7487
+ // BCP: 156484 / 2023 (002075129500001564842023)
7488
+ [false, true, 1].forEach(function (bUnresolved) {
7489
+ var sTitle = "BCP: 156484 / 2023 - type depends on parent entity; unresolved in between: "
7490
+ + bUnresolved;
7491
+
7492
+ QUnit.test(sTitle, function (assert) {
7493
+ var oModel = this.createTeaBusiModel({autoExpandSelect : true}),
7494
+ oTeamContext = oModel.createBindingContext("/TEAMS('1')"),
7495
+ fnSpy = this.spy(ODataMetaModel.prototype, "fetchUI5Type"),
7496
+ oText,
7497
+ sView = '\
7498
+ <Text id="name" text="{Name}"/>', //TODO binding="{}"
7499
+ that = this;
7500
+
7501
+ this.expectChange("name");
7502
+
7503
+ return this.createView(assert, sView, oModel).then(function () {
7504
+ oText = that.oView.byId("name");
7505
+
7506
+ assert.strictEqual(fnSpy.callCount, 0, "no #fetchUI5Type yet");
7507
+
7508
+ that.expectRequest("TEAMS('1')/Name", {value : "Team #1"})
7509
+ .expectChange("name", "Team #1");
7510
+
7511
+ oText.setBindingContext(oTeamContext);
7512
+
7513
+ return that.waitForChanges(assert, "TEAMS/Name");
7514
+ }).then(function () {
7515
+ if (bUnresolved) {
7516
+ that.expectChange("name", null);
7517
+
7518
+ oText.setBindingContext(null);
7519
+
7520
+ return that.waitForChanges(assert, "unresolved");
7521
+ }
7522
+ }).then(function () {
7523
+ if (bUnresolved === 1) {
7524
+ that.expectChange("name", "Team #1");
7525
+
7526
+ oText.setBindingContext(oTeamContext);
7527
+
7528
+ return that.waitForChanges(assert, "TEAMS/Name again");
7529
+ }
7530
+ }).then(function () {
7531
+ var oType = oText.getBinding("text").getType();
7532
+
7533
+ assert.strictEqual(fnSpy.callCount, 1, "1st #fetchUI5Type");
7534
+ assert.strictEqual(oType.getConstraints().maxLength, 40,
7535
+ "Don't try this at home, kids!");
7536
+ sap.ui.test.TestUtils.withNormalizedMessages(function () {
7537
+ assert.throws(function () {
7538
+ oType.validateValue("0123456789012345678901234567890123456789+");
7539
+ }, /EnterTextMaxLength 40/);
7540
+ });
7541
+
7542
+ that.expectRequest("EMPLOYEES('0')/Name", {value : "Frederic Fall"})
7543
+ .expectChange("name", "Frederic Fall");
7544
+
7545
+ oText.setBindingContext(oModel.createBindingContext("/EMPLOYEES('0')"));
7546
+
7547
+ return that.waitForChanges(assert, "EMPLOYEES/Name");
7548
+ }).then(function () {
7549
+ var oType = oText.getBinding("text").getType();
7550
+
7551
+ assert.strictEqual(fnSpy.callCount, 2, "2nd #fetchUI5Type");
7552
+ assert.strictEqual(oType.getConstraints().maxLength, 16,
7553
+ "Don't try this at home, kids!");
7554
+ sap.ui.test.TestUtils.withNormalizedMessages(function () {
7555
+ assert.throws(function () {
7556
+ oType.validateValue("0123456789ABCDEF+");
7557
+ }, /EnterTextMaxLength 16/);
7558
+ });
7559
+ });
7560
+ });
7561
+ });
7562
+
7380
7563
  //*********************************************************************************************
7381
7564
  // Scenario: Modify a property which does not belong to the parent binding's entity, but is
7382
7565
  // related via a navigation property.
@@ -28781,17 +28964,17 @@ sap.ui.define([
28781
28964
  .expectChange("currency");
28782
28965
 
28783
28966
  return this.createView(assert, sView, oModel).then(function () {
28784
- that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
28785
- + "?$select=Price,PublicationID&$skip=0&$top=5", {
28786
- value : []
28787
- })
28788
- .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
28967
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
28789
28968
  + "?$select=ArtistID,IsActiveEntity,Name,defaultChannel", {
28790
28969
  ArtistID : "42",
28791
28970
  IsActiveEntity : true,
28792
28971
  Name : "Hour Frustrated",
28793
28972
  defaultChannel : "Channel 1"
28794
28973
  })
28974
+ .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
28975
+ + "?$select=Price,PublicationID&$skip=0&$top=5", {
28976
+ value : []
28977
+ })
28795
28978
  .expectChange("name", "Hour Frustrated");
28796
28979
 
28797
28980
  oObjectPage = that.oView.byId("objectPage");
@@ -28801,20 +28984,20 @@ sap.ui.define([
28801
28984
 
28802
28985
  return that.waitForChanges(assert);
28803
28986
  }).then(function () {
28804
- that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
28805
- + "?$select=Price,PublicationID&$skip=0&$top=5", {
28806
- value : [{
28807
- Price : "9.99",
28808
- PublicationID : "42-0"
28809
- }]
28810
- })
28811
- .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
28987
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
28812
28988
  + "?$select=ArtistID,IsActiveEntity,Name,defaultChannel", {
28813
28989
  ArtistID : "42",
28814
28990
  IsActiveEntity : true,
28815
28991
  Name : "Hour Frustrated again",
28816
28992
  defaultChannel : "Channel 2"
28817
28993
  })
28994
+ .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
28995
+ + "?$select=Price,PublicationID&$skip=0&$top=5", {
28996
+ value : [{
28997
+ Price : "9.99",
28998
+ PublicationID : "42-0"
28999
+ }]
29000
+ })
28818
29001
  .expectChange("name", "Hour Frustrated again")
28819
29002
  .expectChange("price", ["9.99"])
28820
29003
  .expectChange("channel", ["Channel 2"]);
@@ -28835,20 +29018,20 @@ sap.ui.define([
28835
29018
 
28836
29019
  return that.waitForChanges(assert);
28837
29020
  }).then(function () {
28838
- that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
28839
- + "?$select=Price,PublicationID&$skip=0&$top=5", {
28840
- value : [{
28841
- Price : "10.99",
28842
- PublicationID : "42-0"
28843
- }]
28844
- })
28845
- .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
29021
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
28846
29022
  + "?$select=ArtistID,IsActiveEntity,Name,defaultChannel", {
28847
29023
  ArtistID : "42",
28848
29024
  IsActiveEntity : true,
28849
29025
  Name : "Hour Frustrated again and again",
28850
29026
  defaultChannel : "Channel 3"
28851
29027
  })
29028
+ .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
29029
+ + "?$select=Price,PublicationID&$skip=0&$top=5", {
29030
+ value : [{
29031
+ Price : "10.99",
29032
+ PublicationID : "42-0"
29033
+ }]
29034
+ })
28852
29035
  .expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication('42-0')"
28853
29036
  + "?$select=CurrencyCode", {CurrencyCode : "USD"})
28854
29037
  .expectChange("name", "Hour Frustrated again and again")
@@ -28871,10 +29054,17 @@ sap.ui.define([
28871
29054
  // entity via a bound action using another return value context.
28872
29055
  // The elements referenced via the navigation property must not be taken from the cache.
28873
29056
  // See CPOUI5UISERVICESV3-1686.
28874
- QUnit.test("return value contexts: don't reuse caches if context changed", function (assert) {
29057
+ //
29058
+ // Request an absolute side effect for the table below the R.V.C. (BCP: 2380046603)
29059
+ ["_Publication", "/special.cases.Container/Artists/_Publication"].forEach(function (sPath) {
29060
+ var sTitle = "return value contexts: don't reuse caches if context changed; side effect path: "
29061
+ + sPath;
29062
+
29063
+ QUnit.test(sTitle, function (assert) {
28875
29064
  var oActiveArtistContext,
28876
29065
  oInactiveArtistContext,
28877
29066
  oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
29067
+ oNewActiveArtistContext,
28878
29068
  sView = '\
28879
29069
  <FlexBox id="objectPage">\
28880
29070
  <Text id="id" text="{ArtistID}"/>\
@@ -28920,7 +29110,7 @@ sap.ui.define([
28920
29110
  return that.waitForChanges(assert);
28921
29111
  }).then(function () {
28922
29112
  var oOperation = that.oModel.bindContext("special.cases.EditAction(...)",
28923
- that.oView.getBindingContext(), {$$inheritExpandSelect : true});
29113
+ oActiveArtistContext, {$$inheritExpandSelect : true});
28924
29114
 
28925
29115
  that.expectRequest({
28926
29116
  method : "POST",
@@ -28962,7 +29152,6 @@ sap.ui.define([
28962
29152
  url : "Artists(ArtistID='42',IsActiveEntity=false)/_Publication('42-0')",
28963
29153
  payload : {Price : "8.88"}
28964
29154
  }, {
28965
- "@odata.etag" : "ETag1",
28966
29155
  Price : "8.88"
28967
29156
  })
28968
29157
  .expectChange("price", ["8.88"]);
@@ -28988,7 +29177,7 @@ sap.ui.define([
28988
29177
  return that.waitForChanges(assert);
28989
29178
  }).then(function () {
28990
29179
  var oOperation = that.oModel.bindContext("special.cases.ActivationAction(...)",
28991
- that.oView.getBindingContext(), {$$inheritExpandSelect : true});
29180
+ oInactiveArtistContext, {$$inheritExpandSelect : true});
28992
29181
 
28993
29182
  that.expectRequest({
28994
29183
  method : "POST",
@@ -29007,7 +29196,7 @@ sap.ui.define([
29007
29196
  that.waitForChanges(assert)
29008
29197
  ]);
29009
29198
  }).then(function (aPromiseResults) {
29010
- var oNewActiveArtistContext = aPromiseResults[0];
29199
+ oNewActiveArtistContext = aPromiseResults[0];
29011
29200
 
29012
29201
  // new active artist context causes dependent binding to reload data
29013
29202
  that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
@@ -29023,8 +29212,37 @@ sap.ui.define([
29023
29212
  that.oView.setBindingContext(oNewActiveArtistContext);
29024
29213
 
29025
29214
  return that.waitForChanges(assert);
29215
+ }).then(function () {
29216
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
29217
+ + "?$select=Price,PublicationID&$skip=0&$top=100", {
29218
+ value : [{
29219
+ Price : "8.89", // side effect
29220
+ PublicationID : "42-0"
29221
+ }]
29222
+ })
29223
+ .expectChange("price", ["8.89"]);
29224
+
29225
+ return Promise.all([
29226
+ oNewActiveArtistContext.requestSideEffects([sPath]),
29227
+ that.waitForChanges(assert, "side effect at R.V.C.")
29228
+ ]);
29229
+ }).then(function () {
29230
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)/_Publication"
29231
+ + "?$select=Price,PublicationID&$skip=0&$top=100", {
29232
+ value : [{
29233
+ Price : "8.99", // side effect
29234
+ PublicationID : "42-0"
29235
+ }]
29236
+ })
29237
+ .expectChange("price", ["8.99"]);
29238
+
29239
+ return Promise.all([
29240
+ oActiveArtistContext.requestSideEffects([sPath]),
29241
+ that.waitForChanges(assert, "side effect above operation binding")
29242
+ ]);
29026
29243
  });
29027
29244
  });
29245
+ });
29028
29246
 
29029
29247
  //*********************************************************************************************
29030
29248
  // Scenario: List and details containing a dependent table with an own request. Use
@@ -29299,6 +29517,87 @@ sap.ui.define([
29299
29517
  });
29300
29518
  });
29301
29519
 
29520
+ //*********************************************************************************************
29521
+ // Scenario: An Edm.Stream property is requested as a "late" property and then inherited by an
29522
+ // "Edit" action which replaces the active version by a draft inside the (hidden) ODLB. The
29523
+ // property itself is missing from the response, but is not again requested.
29524
+ // BCP: 2380058514
29525
+ QUnit.test("BCP: 2380058514", function (assert) {
29526
+ var oContext,
29527
+ oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
29528
+ sView = '\
29529
+ <FlexBox>\
29530
+ <Text id="id" text="{ArtistID}"/>\
29531
+ <Text id="isActive" text="{IsActiveEntity}"/>\
29532
+ <Text id="url" text="{Picture}"/>\
29533
+ </FlexBox>',
29534
+ that = this;
29535
+
29536
+ this.expectChange("id")
29537
+ .expectChange("isActive")
29538
+ .expectChange("url");
29539
+
29540
+ return this.createView(assert, sView, oModel).then(function () {
29541
+ that.expectRequest("Artists(ArtistID='42',IsActiveEntity=true)"
29542
+ + "?$select=ArtistID,IsActiveEntity,Picture", {
29543
+ ArtistID : "42",
29544
+ IsActiveEntity : true
29545
+ // Picture property not seen here -> "Picture@$ui5.noData" : true
29546
+ // "Picture@odata.mediaContentType" etc. intentionally left out here
29547
+ })
29548
+ .expectChange("id", "42")
29549
+ .expectChange("isActive", "Yes")
29550
+ .expectChange("url",
29551
+ "/special/cases/Artists(ArtistID='42',IsActiveEntity=true)/Picture");
29552
+
29553
+ oContext = oModel.getKeepAliveContext("/Artists(ArtistID='42',IsActiveEntity=true)");
29554
+ that.oView.setBindingContext(oContext);
29555
+
29556
+ return that.waitForChanges(assert);
29557
+ }).then(function () {
29558
+ var oOperation = that.oModel.bindContext("special.cases.EditAction(...)", oContext,
29559
+ {$$inheritExpandSelect : true});
29560
+
29561
+ assert.deepEqual(oContext.getObject(), {
29562
+ ArtistID : "42",
29563
+ IsActiveEntity : true,
29564
+ "Picture@$ui5.noData" : true
29565
+ });
29566
+
29567
+ that.expectRequest({
29568
+ method : "POST",
29569
+ url : "Artists(ArtistID='42',IsActiveEntity=true)/special.cases.EditAction"
29570
+ + "?$select=ArtistID,IsActiveEntity,Picture",
29571
+ payload : {}
29572
+ }, {
29573
+ ArtistID : "42",
29574
+ IsActiveEntity : false
29575
+ // Picture property not seen here -> "Picture@$ui5.noData" : true
29576
+ // "Picture@odata.mediaContentType" etc. intentionally left out here
29577
+ });
29578
+
29579
+ return Promise.all([
29580
+ // code under test
29581
+ oOperation.execute(undefined, false, null, /*bReplaceWithRVC*/true),
29582
+ that.waitForChanges(assert)
29583
+ ]);
29584
+ }).then(function (aResults) {
29585
+ assert.deepEqual(aResults[0].getObject(), {
29586
+ ArtistID : "42",
29587
+ IsActiveEntity : false,
29588
+ "Picture@$ui5.noData" : true
29589
+ });
29590
+
29591
+ that.expectChange("isActive", "No")
29592
+ .expectChange("url",
29593
+ "/special/cases/Artists(ArtistID='42',IsActiveEntity=false)/Picture");
29594
+
29595
+ that.oView.setBindingContext(aResults[0]);
29596
+
29597
+ return that.waitForChanges(assert);
29598
+ });
29599
+ });
29600
+
29302
29601
  //*********************************************************************************************
29303
29602
  // Scenario: Call an action which returns the binding parameter as return value. Expect that
29304
29603
  // the result is copied back to the binding parameter.
@@ -44093,6 +44392,9 @@ sap.ui.define([
44093
44392
  // still unresolved. The object page must be useable nevertheless. In the end resolve the
44094
44393
  // list and see that it is in sync with the object page.
44095
44394
  // JIRA: CPOUI5ODATAV4-1407
44395
+ //
44396
+ // Reset the keep-alive status and request the active entity again in this scenario.
44397
+ // BCP: 441477 / 2023 (002075129400004414772023)
44096
44398
  // Steps:
44097
44399
  // (1) and (2) initialization in different order
44098
44400
  // (3) edit action
@@ -44409,6 +44711,10 @@ sap.ui.define([
44409
44711
  return that.waitForChanges(assert, "(6) cancel");
44410
44712
  }).then(function () {
44411
44713
  if (oFixture.list === 7) {
44714
+ oActiveContext.setKeepAlive(false);
44715
+ oActiveContext = that.oModel.getKeepAliveContext(
44716
+ "/Artists(ArtistID='A1',IsActiveEntity=true)", true,
44717
+ {$$patchWithoutSideEffects : true});
44412
44718
  initializeList(6);
44413
44719
  }
44414
44720
 
@@ -44846,6 +45152,259 @@ sap.ui.define([
44846
45152
  });
44847
45153
  });
44848
45154
 
45155
+ //*********************************************************************************************
45156
+ // Scenario: Flexible Column Layout, ODataModel#getKeepAliveContext
45157
+ // Object page requests a kept-alive context from an empty list. See that the object page
45158
+ // request's $select contains all properties from the list's $select even if there has not been
45159
+ // a late property yet.
45160
+ // Note that getKeepAliveContext requests the key properties (and poss. the messages). So in
45161
+ // order to have no late properties yet, the list must show all key properties, and messages
45162
+ // must not be requested. The test only has the shared property "Name" to avoid timing issues.
45163
+ // JIRA: CPOUI5ODATAV4-2190
45164
+ QUnit.test("getKeepAliveContext: properties from the list's $select", function (assert) {
45165
+ var oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
45166
+ sView = '\
45167
+ <Table id="list" growing="true" growingThreshold="1" items="{path : \'Artists\',\
45168
+ parameters : {$$getKeepAliveContext : true, $$ownRequest : true}}">\
45169
+ <Text id="id" text="{ArtistID}"/>\
45170
+ <Text id="isActiveEntity" text="{IsActiveEntity}"/>\
45171
+ <Text id="listName" text="{Name}"/>\
45172
+ <Text id="listFriend" text="{BestFriend/Name}"/>\
45173
+ </Table>\
45174
+ <FlexBox id="objectPage">\
45175
+ <Text id="name" text="{Name}"/>\
45176
+ <Text id="friend" text="{BestFriend/Name}"/>\
45177
+ </FlexBox>',
45178
+ that = this;
45179
+
45180
+ this.expectChange("id", [])
45181
+ .expectChange("isActiveEntity", [])
45182
+ .expectChange("listName", [])
45183
+ .expectChange("listFriend", [])
45184
+ .expectChange("name")
45185
+ .expectChange("friend");
45186
+
45187
+ return this.createView(assert, sView, oModel).then(function () {
45188
+ that.expectRequest({
45189
+ batchNo : 1,
45190
+ url : "Artists?$select=ArtistID,IsActiveEntity,Name"
45191
+ + "&$expand=BestFriend($select=ArtistID,IsActiveEntity,Name)&$skip=0&$top=1"
45192
+ }, {
45193
+ value : [{
45194
+ ArtistID : "1",
45195
+ IsActiveEntity : true,
45196
+ Name : "The Who",
45197
+ BestFriend : {
45198
+ ArtistID : "2",
45199
+ IsActiveEntity : true,
45200
+ Name : "The The"
45201
+ }
45202
+ }]
45203
+ })
45204
+ .expectRequest({
45205
+ batchNo : 1,
45206
+ url : "Artists(ArtistID='3',IsActiveEntity=false)"
45207
+ + "?$select=ArtistID,IsActiveEntity,Name"
45208
+ + "&$expand=BestFriend($select=ArtistID,IsActiveEntity,Name)"
45209
+ }, {
45210
+ ArtistID : "3",
45211
+ IsActiveEntity : false,
45212
+ Name : "The Beatles",
45213
+ BestFriend : {
45214
+ ArtistID : "4",
45215
+ IsActiveEntity : true,
45216
+ Name : "The Rolling Stones"
45217
+ }
45218
+ })
45219
+ .expectChange("id", ["1"])
45220
+ .expectChange("isActiveEntity", ["Yes"])
45221
+ .expectChange("listName", ["The Who"])
45222
+ .expectChange("listFriend", ["The The"])
45223
+ .expectChange("name", "The Beatles")
45224
+ .expectChange("friend", "The Rolling Stones");
45225
+
45226
+ that.oView.byId("list").setBindingContext(oModel.createBindingContext("/"));
45227
+ that.oView.byId("objectPage").setBindingContext(
45228
+ oModel.getKeepAliveContext("/Artists(ArtistID='3',IsActiveEntity=false)"));
45229
+
45230
+ return that.waitForChanges(assert);
45231
+ });
45232
+ });
45233
+
45234
+ //*********************************************************************************************
45235
+ // Scenario: Flexible Column Layout, ODataModel#getKeepAliveContext
45236
+ // Object page requests a kept-alive context. The context's keep-alive status is removed, either
45237
+ // still in the temporary binding or hidden in the $$getKeepAliveContext binding. Later a
45238
+ // kept-alive context for the same path is requested; its data must be read from the server
45239
+ // again.
45240
+ // BCP: 441477 / 2023 (002075129400004414772023)
45241
+ [false, true].forEach(function (bTemporary) {
45242
+ var sTitle = "BCP: 441477 / 2023: getKeepAliveContext, temporary=" + bTemporary;
45243
+
45244
+ QUnit.test(sTitle, function (assert) {
45245
+ var oContext,
45246
+ oListBinding,
45247
+ oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
45248
+ oObjectPage,
45249
+ sView = '\
45250
+ <Table id="list" growing="true" growingThreshold="1"\
45251
+ items="{path : \'/Artists\', parameters : {$$getKeepAliveContext : true},\
45252
+ suspended : true}">\
45253
+ <Text id="listName" text="{Name}"/>\
45254
+ </Table>\
45255
+ <FlexBox id="objectPage">\
45256
+ <Text id="name" text="{Name}"/>\
45257
+ </FlexBox>',
45258
+ that = this;
45259
+
45260
+ this.expectChange("listName", [])
45261
+ .expectChange("name");
45262
+
45263
+ return this.createView(assert, sView, oModel).then(function () {
45264
+ that.expectRequest("Artists(ArtistID='3',IsActiveEntity=false)"
45265
+ + "?$select=ArtistID,IsActiveEntity,Name", {
45266
+ ArtistID : "3",
45267
+ IsActiveEntity : false,
45268
+ Name : "The Beatles"
45269
+ })
45270
+ .expectChange("name", "The Beatles");
45271
+
45272
+ oContext = oModel.getKeepAliveContext("/Artists(ArtistID='3',IsActiveEntity=false)");
45273
+ oObjectPage = that.oView.byId("objectPage");
45274
+ oObjectPage.setBindingContext(oContext);
45275
+
45276
+ return that.waitForChanges(assert, "1st getKeepAliveContext");
45277
+ }).then(function () {
45278
+ if (!bTemporary) {
45279
+ that.expectRequest("Artists?$select=ArtistID,IsActiveEntity,Name"
45280
+ + "&$skip=0&$top=1", {
45281
+ value : [{
45282
+ ArtistID : "1",
45283
+ IsActiveEntity : true,
45284
+ Name : "The Who"
45285
+ }]
45286
+ })
45287
+ .expectChange("listName", ["The Who"]);
45288
+
45289
+ oListBinding = that.oView.byId("list").getBinding("items");
45290
+ oListBinding.resume();
45291
+
45292
+ return that.waitForChanges(assert, "transfer to the list");
45293
+ }
45294
+ }).then(function () {
45295
+ if (!bTemporary) {
45296
+ assert.strictEqual(oContext.getBinding(), oListBinding, "transferred to the list");
45297
+ }
45298
+
45299
+ that.expectChange("name", null);
45300
+
45301
+ oObjectPage.setBindingContext(null); // unbind before destruction
45302
+
45303
+ // code under test
45304
+ oContext.setKeepAlive(false);
45305
+
45306
+ return that.waitForChanges(assert, "setKeepAlive(false)");
45307
+ }).then(function () {
45308
+ that.expectRequest("Artists(ArtistID='3',IsActiveEntity=false)"
45309
+ + "?$select=ArtistID,IsActiveEntity,Name", {
45310
+ ArtistID : "3",
45311
+ IsActiveEntity : false,
45312
+ Name : "The Beatles *"
45313
+ })
45314
+ .expectChange("name", "The Beatles *");
45315
+
45316
+ oContext = oModel.getKeepAliveContext("/Artists(ArtistID='3',IsActiveEntity=false)");
45317
+ oObjectPage.setBindingContext(oContext);
45318
+
45319
+ return that.waitForChanges(assert, "2nd getKeepAliveContext");
45320
+ });
45321
+ });
45322
+ });
45323
+
45324
+ //*********************************************************************************************
45325
+ // Scenario: Flexible Column Layout, ODataModel#getKeepAliveContext
45326
+ // Object page requests a hidden kept-alive context for a list with data. The context's
45327
+ // keep-alive status is removed. Later the entity is changed on the server and then loaded via
45328
+ // paging, it must show the new data.
45329
+ // BCP: 441477 / 2023 (002075129400004414772023)
45330
+ [false, true].forEach(function (bETag) {
45331
+ var sTitle = "BCP: 441477 / 2023: getKeepAliveContext & paging, eTag=" + bETag;
45332
+
45333
+ QUnit.test(sTitle, function (assert) {
45334
+ var oContext,
45335
+ oModel = this.createSpecialCasesModel({autoExpandSelect : true}),
45336
+ oObjectPage,
45337
+ sView = '\
45338
+ <Table id="list" growing="true" growingThreshold="1" \
45339
+ items="{path : \'/Artists\', parameters : {$$getKeepAliveContext : true}}">\
45340
+ <Text id="listName" text="{Name}"/>\
45341
+ </Table>\
45342
+ <FlexBox id="objectPage">\
45343
+ <Text id="name" text="{Name}"/>\
45344
+ </FlexBox>',
45345
+ that = this;
45346
+
45347
+ this.expectRequest("Artists?$select=ArtistID,IsActiveEntity,Name"
45348
+ + "&$skip=0&$top=1", {
45349
+ value : [{
45350
+ ArtistID : "1",
45351
+ IsActiveEntity : true,
45352
+ Name : "The Who"
45353
+ }]
45354
+ })
45355
+ .expectChange("listName", ["The Who"])
45356
+ .expectChange("name");
45357
+
45358
+ return this.createView(assert, sView, oModel).then(function () {
45359
+ var oResponse = {
45360
+ ArtistID : "3",
45361
+ IsActiveEntity : false,
45362
+ Name : "The Beatles"
45363
+ };
45364
+
45365
+ if (bETag) {
45366
+ oResponse["@odata.etag"] = "etag1";
45367
+ }
45368
+ that.expectRequest("Artists(ArtistID='3',IsActiveEntity=false)"
45369
+ + "?$select=ArtistID,IsActiveEntity,Name",
45370
+ oResponse)
45371
+ .expectChange("name", "The Beatles");
45372
+
45373
+ oContext = oModel.getKeepAliveContext("/Artists(ArtistID='3',IsActiveEntity=false)");
45374
+ oObjectPage = that.oView.byId("objectPage");
45375
+ oObjectPage.setBindingContext(oContext);
45376
+
45377
+ return that.waitForChanges(assert, "getKeepAliveContext");
45378
+ }).then(function () {
45379
+ that.expectChange("name", null);
45380
+
45381
+ oObjectPage.setBindingContext(null); // unbind before destruction
45382
+
45383
+ // code under test
45384
+ oContext.setKeepAlive(false);
45385
+
45386
+ return that.waitForChanges(assert, "setKeepAlive(false)");
45387
+ }).then(function () {
45388
+ var oResponse = {
45389
+ ArtistID : "3",
45390
+ IsActiveEntity : false,
45391
+ Name : "The Beatles *"
45392
+ };
45393
+
45394
+ if (bETag) {
45395
+ oResponse["@odata.etag"] = "etag2";
45396
+ }
45397
+ that.expectRequest("Artists?$select=ArtistID,IsActiveEntity,Name&$skip=1&$top=1",
45398
+ {value : [oResponse]})
45399
+ .expectChange("listName", [, "The Beatles *"]);
45400
+
45401
+ that.oView.byId("list").requestItems();
45402
+
45403
+ return that.waitForChanges(assert, "request more items");
45404
+ });
45405
+ });
45406
+ });
45407
+
44849
45408
  //*********************************************************************************************
44850
45409
  // Scenario: List report with absolute binding, object page with a late property. Ensure that
44851
45410
  // the late property is not requested for all rows of the list, but only for the single row that