11import userEvent from '@testing-library/user-event' ;
22import MockAdapter from 'axios-mock-adapter/types' ;
3+
34import {
45 act ,
56 render as baseRender ,
67 screen ,
78 initializeMocks ,
89 waitFor ,
9- } from '../../testUtils' ;
10+ } from '@src/testUtils' ;
11+ import { ToastActionData } from '@src/generic/toast-context' ;
1012
1113import IframePreviewLibraryXBlockChanges , { LibraryChangesMessageData } from '.' ;
1214import { messageTypes } from '../constants' ;
1315import { libraryBlockChangesUrl } from '../data/api' ;
14- import { ToastActionData } from '../../generic/toast-context' ;
1516
1617const usageKey = 'block-v1:UNIX+UX1+2025_T3+type@unit+block@1' ;
1718const defaultEventData : LibraryChangesMessageData = {
@@ -20,10 +21,12 @@ const defaultEventData: LibraryChangesMessageData = {
2021 upstreamBlockId : 'lct:org:lib1:unit:1' ,
2122 upstreamBlockVersionSynced : 1 ,
2223 isContainer : false ,
24+ isLocallyModified : false ,
25+ blockType : 'html' ,
2326} ;
2427
2528const mockSendMessageToIframe = jest . fn ( ) ;
26- jest . mock ( '../.. /generic/hooks/context/hooks' , ( ) => ( {
29+ jest . mock ( '@src /generic/hooks/context/hooks' , ( ) => ( {
2730 useIframe : ( ) => ( {
2831 iframeRef : { current : { contentWindow : { } as HTMLIFrameElement } } ,
2932 setIframeRef : ( ) => { } ,
@@ -60,7 +63,6 @@ describe('<IframePreviewLibraryXBlockChanges />', () => {
6063 expect ( await screen . findByText ( 'Preview changes: Test block' ) ) . toBeInTheDocument ( ) ;
6164 expect ( await screen . findByRole ( 'button' , { name : 'Accept changes' } ) ) . toBeInTheDocument ( ) ;
6265 expect ( await screen . findByRole ( 'button' , { name : 'Ignore changes' } ) ) . toBeInTheDocument ( ) ;
63- expect ( await screen . findByRole ( 'button' , { name : 'Cancel' } ) ) . toBeInTheDocument ( ) ;
6466 expect ( await screen . findByRole ( 'tab' , { name : 'New version' } ) ) . toBeInTheDocument ( ) ;
6567 expect ( await screen . findByRole ( 'tab' , { name : 'Old version' } ) ) . toBeInTheDocument ( ) ;
6668 } ) ;
@@ -132,4 +134,59 @@ describe('<IframePreviewLibraryXBlockChanges />', () => {
132134 } ) ;
133135 expect ( screen . queryByText ( 'Preview changes: Test block' ) ) . not . toBeInTheDocument ( ) ;
134136 } ) ;
137+
138+ it ( 'should render modal of text with local changes' , async ( ) => {
139+ render ( { ...defaultEventData , isLocallyModified : true } ) ;
140+
141+ expect ( await screen . findByText ( 'Preview changes: Test block' ) ) . toBeInTheDocument ( ) ;
142+
143+ expect ( screen . getByText ( 'This library content has local edits.' ) ) . toBeInTheDocument ( ) ;
144+ expect ( await screen . findByRole ( 'button' , { name : 'Update to published library content' } ) ) . toBeInTheDocument ( ) ;
145+ expect ( await screen . findByRole ( 'button' , { name : 'Keep course content' } ) ) . toBeInTheDocument ( ) ;
146+ expect ( await screen . findByRole ( 'tab' , { name : 'Course content' } ) ) . toBeInTheDocument ( ) ;
147+ expect ( await screen . findByRole ( 'tab' , { name : 'Published library content' } ) ) . toBeInTheDocument ( ) ;
148+ } ) ;
149+
150+ it ( 'update changes works' , async ( ) => {
151+ const user = userEvent . setup ( ) ;
152+ axiosMock . onPost ( libraryBlockChangesUrl ( usageKey ) ) . reply ( 200 , { } ) ;
153+ render ( { ...defaultEventData , isLocallyModified : true } ) ;
154+
155+ expect ( await screen . findByText ( 'Preview changes: Test block' ) ) . toBeInTheDocument ( ) ;
156+ const acceptBtn = await screen . findByRole ( 'button' , { name : 'Update to published library content' } ) ;
157+ await user . click ( acceptBtn ) ;
158+ const confirmBtn = await screen . findByRole ( 'button' , { name : 'Discard local edits and update' } ) ;
159+ await user . click ( confirmBtn ) ;
160+
161+ await waitFor ( ( ) => {
162+ expect ( mockSendMessageToIframe ) . toHaveBeenCalledWith (
163+ messageTypes . completeXBlockEditing ,
164+ { locator : usageKey } ,
165+ ) ;
166+ expect ( axiosMock . history . post . length ) . toEqual ( 1 ) ;
167+ expect ( axiosMock . history . post [ 0 ] . url ) . toEqual ( libraryBlockChangesUrl ( usageKey ) ) ;
168+ } ) ;
169+ expect ( screen . queryByText ( 'Preview changes: Test block' ) ) . not . toBeInTheDocument ( ) ;
170+ } ) ;
171+
172+ it ( 'keep changes work' , async ( ) => {
173+ const user = userEvent . setup ( ) ;
174+ axiosMock . onDelete ( libraryBlockChangesUrl ( usageKey ) ) . reply ( 200 , { } ) ;
175+ render ( { ...defaultEventData , isLocallyModified : true } ) ;
176+
177+ expect ( await screen . findByText ( 'Preview changes: Test block' ) ) . toBeInTheDocument ( ) ;
178+ const ignoreBtn = await screen . findByRole ( 'button' , { name : 'Keep course content' } ) ;
179+ await user . click ( ignoreBtn ) ;
180+ const ignoreConfirmBtn = ( await screen . findAllByRole ( 'button' , { name : 'Keep course content' } ) ) [ 0 ] ;
181+ await user . click ( ignoreConfirmBtn ) ;
182+ await waitFor ( ( ) => {
183+ expect ( mockSendMessageToIframe ) . toHaveBeenCalledWith (
184+ messageTypes . completeXBlockEditing ,
185+ { locator : usageKey } ,
186+ ) ;
187+ expect ( axiosMock . history . delete . length ) . toEqual ( 1 ) ;
188+ expect ( axiosMock . history . delete [ 0 ] . url ) . toEqual ( libraryBlockChangesUrl ( usageKey ) ) ;
189+ } ) ;
190+ expect ( screen . queryByText ( 'Preview changes: Test block' ) ) . not . toBeInTheDocument ( ) ;
191+ } ) ;
135192} ) ;
0 commit comments