You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rave.apache.org by ca...@apache.org on 2011/08/25 23:00:40 UTC

svn commit: r1161760 - in /incubator/rave/trunk/rave-portal/src: main/java/org/apache/rave/portal/model/ main/java/org/apache/rave/portal/service/ main/java/org/apache/rave/portal/service/impl/ main/java/org/apache/rave/portal/web/api/rpc/ main/webapp/...

Author: carlucci
Date: Thu Aug 25 21:00:40 2011
New Revision: 1161760

URL: http://svn.apache.org/viewvc?rev=1161760&view=rev
Log:
RAVE-202: re-order page sequences.  This is a sub task of RAVE-163: Page Management CRUD

Modified:
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/RegionWidget.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
    incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
    incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
    incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js
    incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js
    incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java
    incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
    incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/Page.java Thu Aug 25 21:00:40 2011
@@ -28,12 +28,15 @@ import java.util.List;
 /**
  * A page, which consists of regions, and which may be owned by a {@link User} (note the ownership will likely need to
  * become more flexible to enable things like group ownership in the future).
+ * 
+ * TODO: not all database providers will be able to support deferrable constraints
+ * so for the time being I'm commenting out the owner/render sequence since it
+ * will get updated in batches and blow up
+ * @UniqueConstraint(columnNames={"owner_id","render_sequence"}
+ * 
  */
 @Entity
-@Table(name="page", uniqueConstraints={
-                        @UniqueConstraint(columnNames={"owner_id","name"}),
-                        @UniqueConstraint(columnNames={"owner_id","render_sequence"})}
-)
+@Table(name="page", uniqueConstraints={@UniqueConstraint(columnNames={"owner_id","name"})})
 @SequenceGenerator(name="pageIdSeq", sequenceName = "page_id_seq")
 @NamedQueries({
         @NamedQuery(name = "Page.getByUserId", query="SELECT p FROM Page p WHERE p.owner.id = :userId ORDER BY p.renderSequence")

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/RegionWidget.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/RegionWidget.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/RegionWidget.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/model/RegionWidget.java Thu Aug 25 21:00:40 2011
@@ -205,6 +205,15 @@ public class RegionWidget implements Bas
 
     @Override
     public String toString() {
-        return "RegionWidget{" + "id=" + id + ", widget=" + widget + ", region=" + region + ", renderPosition=" + renderPosition + ", renderOrder=" + renderOrder + ", collapsed=" + collapsed + ", preferences=" + preferences + '}';
+        StringBuilder sb = new StringBuilder();
+        sb.append("RegionWidget{");
+        sb.append("id=");
+        sb.append(id);
+        sb.append(",widget=");
+        sb.append(widget);
+        sb.append(",region=");
+        sb.append(region);
+        sb.append("}");
+        return sb.toString();
     }
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/PageService.java Thu Aug 25 21:00:40 2011
@@ -111,4 +111,22 @@ public interface PageService {
      * @return the region from which the widget was deleted
      */
     Region removeWidgetFromPage(long regionWidgetId);
+    
+    /**
+     * Moves a page to be rendered after another page in order for a user
+     * 
+     * @param pageId the pageId of the page to move
+     * @param moveAfterPageId the pageId of the page you want to move after or 
+     *                        -1 if you want this to be the first page
+     * @return the updated Page object containing its new render sequence
+     */
+    Page movePage(long pageId, long moveAfterPageId);
+    
+    /**
+     * Moves a page to be rendered as the first page for a user
+     * 
+     * @param pageId the pageId of the page to move to the default position
+     * @return the updated Page object containing its new render sequence
+     */
+    Page movePageToDefault(long pageId);    
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/service/impl/DefaultPageService.java Thu Aug 25 21:00:40 2011
@@ -50,6 +50,8 @@ public class DefaultPageService implemen
     private final PageLayoutRepository pageLayoutRepository;
     private final UserService userService;    
     private final String defaultPageName;
+    
+    private final long MOVE_PAGE_DEFAULT_POSITION_INDEX = -1L;
 
     @Autowired
     public DefaultPageService(PageRepository pageRepository, 
@@ -146,6 +148,18 @@ public class DefaultPageService implemen
         Region region = page.getRegions().get(0);
         return createWidgetInstance(widget, region, 0);
     }
+    
+    @Override
+    @Transactional
+    public Page movePage(long pageId, long moveAfterPageId) {
+        return doMovePage(pageId, moveAfterPageId);
+    }    
+    
+    @Override
+    @Transactional
+    public Page movePageToDefault(long pageId) {    
+        return doMovePage(pageId, MOVE_PAGE_DEFAULT_POSITION_INDEX);    
+    }
 
     private RegionWidget createWidgetInstance(Widget widget, Region region, int position) {
         RegionWidget regionWidget = new RegionWidget();
@@ -237,5 +251,41 @@ public class DefaultPageService implemen
                 pageRepository.save(page);
             }
         }       
-    }
+    } 
+    
+    private Page doMovePage(long pageId, long moveAfterPageId) {
+        // get the logged in user
+        User user = userService.getAuthenticatedUser();
+
+        // get the page to move and the page to move after
+        Page movingPage = pageRepository.get(pageId);
+        Page afterPage = null;
+        int newIndex = 0;
+        
+        // check to see if we should move the page to beginning
+        if (moveAfterPageId != MOVE_PAGE_DEFAULT_POSITION_INDEX) {
+            afterPage = pageRepository.get(moveAfterPageId);
+        }
+
+        // get all of the user's pages
+        // the pageRepository returns an un-modifiable list
+        // so we need to create a modifyable arraylist
+        List<Page> pages = new ArrayList<Page>(pageRepository.getAllPages(user.getId()));
+
+        // first remove it from the list         
+        if (!pages.remove(movingPage)) {
+            throw new RuntimeException("unable to find pageId " + pageId + " attempted to be moved for user " + user);
+        }
+
+        // ...now re-insert in new location
+        if (afterPage != null) {
+            newIndex = pages.indexOf(afterPage) + 1;
+        }
+        pages.add(newIndex, movingPage);
+
+        // persist the new page order
+        updatePageRenderSequences(pages);
+        
+        return movingPage;
+    }    
 }
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java (original)
+++ incubator/rave/trunk/rave-portal/src/main/java/org/apache/rave/portal/web/api/rpc/PageApi.java Thu Aug 25 21:00:40 2011
@@ -126,6 +126,15 @@ public class PageApi {
         }.getResult();
     }
     
+
+    /**
+     * Adds a new page
+     * 
+     * @param pageName the new page name
+     * @param pageLayoutCode the layout code for this new page
+     * @return an {@link RpcOperation} containing the new page or any
+     *         errors encountered.
+     */
     @ResponseBody
     @RequestMapping(method = RequestMethod.POST, value = "add")
     public RpcResult<Page> addPage(@RequestParam final String pageName,
@@ -137,4 +146,30 @@ public class PageApi {
              }
         }.getResult();        
     }
-}
+    
+    /**
+     * Moves a page to a new render position
+     * 
+     * @param pageId the pageId to move
+     * @param moveAfterPageId the pageId to move after in render order
+     * @return an {@link RpcOperation} containing the updated page or any
+     *         errors encountered.
+     */
+    @ResponseBody
+    @RequestMapping(method = RequestMethod.POST, value = "{pageId}/move")
+    public RpcResult<Page> movePage(@PathVariable final long pageId, 
+                                    @RequestParam(required=false) final Long moveAfterPageId) {
+        return new RpcOperation<Page>() {
+            @Override
+            public Page execute() {
+                Page page = null;
+                if (moveAfterPageId == null) {
+                    page = pageService.movePageToDefault(pageId);
+                } else {
+                    page = pageService.movePage(pageId, moveAfterPageId);
+                }
+                return page;
+            }
+        }.getResult();        
+    }
+}
\ No newline at end of file

Modified: incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/WEB-INF/views/home.jsp Thu Aug 25 21:00:40 2011
@@ -50,7 +50,13 @@
                          <c:when test="${page.id == userPage.id}">true</c:when>
                          <c:otherwise>false</c:otherwise>
                      </c:choose>
-                 </c:set>                             
+                 </c:set>      
+                 <c:set var="hasOnlyOnePage">
+                      <c:choose>
+                         <c:when test="${fn:length(pages) == 1}">true</c:when>
+                         <c:otherwise>false</c:otherwise>
+                     </c:choose>
+                 </c:set>                       
                  <div id="tab-${userPage.id}" class="rave-ui-tab<c:if test="${isCurrentPage}"> rave-ui-tab-selected</c:if>">
                     <div id="pageTitle-${userPage.id}" class="page-title" onclick="rave.viewPage(${userPage.id});"><c:out value="${userPage.name}"/></div>
                     <c:if test="${isCurrentPage}">                   
@@ -58,8 +64,8 @@
                             <span id="pageMenuButton" class="ui-icon ui-icon-circle-triangle-s" title="Page Actions Menu"></span>
                             <div id="pageMenu" class="page-menu">
                                 <div id="pageMenuEdit" class="page-menu-item">Edit Page</div>
-                                <div id="pageMenuDelete" class="page-menu-item<c:if test='${fn:length(pages) == 1}'> page-menu-item-disabled</c:if>">Delete Page</div>
-                                <div id="pageMenuMove" class="page-menu-item">Move Page</div>
+                                <div id="pageMenuDelete" class="page-menu-item<c:if test='${hasOnlyOnePage}'> page-menu-item-disabled</c:if>">Delete Page</div>
+                                <div id="pageMenuMove" class="page-menu-item<c:if test='${hasOnlyOnePage}'> page-menu-item-disabled</c:if>">Move Page</div>
                             </div>
                         </div>
                     </c:if>
@@ -119,6 +125,21 @@
             </fieldset>
         </form>
     </div>    
+    <div id="movePageDialog" title="Move Page" class="dialog">
+        <div>Move this page:</div>
+        <form id="movePageForm">
+            <select id="moveAfterPageId">
+                <c:if test="${page.renderSequence != 1}">
+                    <option value="-1">To First Tab (Set as Default)</option>
+                </c:if>
+                <c:forEach var="userPage" items="${pages}">
+                    <c:if test="${userPage.id != page.id}">
+                        <option value="${userPage.id}">After <c:out value="${userPage.name}"/></option>
+                    </c:if>
+                </c:forEach>
+            </select>
+        </form>
+    </div>
     <script src="//cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js"></script>
     <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
     <script src="//ajax.aspnetcdn.com/ajax/jquery.ui/1.8.13/jquery-ui.min.js"></script>

Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_api.js Thu Aug 25 21:00:40 2011
@@ -166,6 +166,28 @@ rave.api = rave.api || (function() {
                     }
                 }).error(handleError);
         }
+        
+        function movePage(args) {
+            // the moveAfterPageId attribute could be undefined if moving
+            // to the first position. In that case don't send a moveAfterPageId
+            // post parameter
+            var data = {};
+            if (args.moveAfterPageId) {
+                data["moveAfterPageId"] = args.moveAfterPageId;
+            }
+            
+            $.post(rave.getContext() + path + "page/" + args.pageId + "/move",
+                data,
+                function(result) {
+                    if (result.error) {                   
+                        handleRpcError(result);                        
+                    } else {
+                        if (typeof args.successCallback == 'function') {
+                            args.successCallback(result);
+                        }
+                    }
+                }).error(handleError);
+        }        
 
         //TODO: Create a more robust error handling system and interrogation of RPC results
         function handleRpcError(rpcResult) {
@@ -187,7 +209,8 @@ rave.api = rave.api || (function() {
             moveWidget : moveWidgetOnPage,
             addWidgetToPage : addWidgetToPage,
             removeWidget : deleteWidgetOnPage,
-            addPage: addPage
+            addPage: addPage,
+            movePage: movePage
         };
 
     })();

Modified: incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js (original)
+++ incubator/rave/trunk/rave-portal/src/main/webapp/script/rave_layout.js Thu Aug 25 21:00:40 2011
@@ -19,6 +19,8 @@
 
 var rave = rave || {};
 rave.layout = rave.layout || (function() {
+    var MOVE_PAGE_DEFAULT_POSITION_IDX = -1;
+    
     var $tab_title_input = $("#tab_title"),
         $page_layout_input = $("#pageLayout");
         
@@ -43,6 +45,26 @@ rave.layout = rave.layout || (function()
             }
     });        
    
+    // the modal dialog for moving a page
+    var $movePageDialog = $("#movePageDialog").dialog({
+            autoOpen: false,
+            modal: true,
+            buttons: {
+                    Move: function() {
+                            movePage();                            
+                    },
+                    Cancel: function() {
+                            $( this ).dialog( "close" );
+                    }
+            },
+            open: function() {
+                    $("#moveAfterPageId").focus();
+            },
+            close: function() {
+                    $("#movePageForm")[0].reset();                    
+            }
+    });        
+   
     // define the form object    
     var $form = $("#pageForm", $dialog);  
     
@@ -98,14 +120,16 @@ rave.layout = rave.layout || (function()
                 });
             }
 
-            // setup the edit page menu item
-            $menuItemMove.bind('click', function(event) {
-                alert("Move not yet implemented!");
-                pageMenu.hide();
-                // prevent the menu button click event from bubbling up to parent 
-                // DOM object event handlers such as the page tab click event
-                event.stopPropagation();
-            });       
+            // setup the edit page menu item if it is not disabled
+            if (!$menuItemDelete.hasClass("page-menu-item-disabled")) {
+                $menuItemMove.bind('click', function(event) {
+                    pageMenu.hide();                 
+                    $movePageDialog.dialog("open");                                             
+                    // prevent the menu button click event from bubbling up to parent 
+                    // DOM object event handlers such as the page tab click event
+                    event.stopPropagation();
+                });      
+            }
 
             // close the page menu if the user clicks outside of it           
             $("html").click(pageMenu.hide);
@@ -138,12 +162,29 @@ rave.layout = rave.layout || (function()
     }      
     
     /**
+     * Submits the RPC call to move the page to a new render sequence
+     */        
+    function movePage() {
+        var moveAfterPageId = $("#moveAfterPageId").val();        
+        var args = { pageId: $("#currentPageId").val(),
+                     successCallback: function(result) { rave.viewPage(result.result.id); }
+                   };
+       
+        if (moveAfterPageId != MOVE_PAGE_DEFAULT_POSITION_IDX) {
+            args["moveAfterPageId"] = moveAfterPageId;
+        }
+                          
+        // send the rpc request to move the new page
+        rave.api.rpc.movePage(args);              
+    }          
+    
+    /**
      * Returns the pageId of the currently viewed page
      */
     function getCurrentPageId() {
         return $("#currentPageId").val();
     }
-   
+       
    /***
     * initializes the rave.layout namespace code
     */

Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/service/PageServiceTest.java Thu Aug 25 21:00:40 2011
@@ -65,16 +65,16 @@ public class PageServiceTest {
     private User user;
     private PageLayout pageLayout;
     private String defaultPageName = "Main";
-    private Page page;
+    private Page page, page2;
     private List<Page> pageList;
 
     @Before
     public void setup() {
 
-        pageRepository = createNiceMock(PageRepository.class);
-        regionRepository = createNiceMock(RegionRepository.class);
-        widgetRepository = createNiceMock(WidgetRepository.class);
-        regionWidgetRepository = createNiceMock(RegionWidgetRepository.class);
+        pageRepository = createMock(PageRepository.class);
+        regionRepository = createMock(RegionRepository.class);
+        widgetRepository = createMock(WidgetRepository.class);
+        regionWidgetRepository = createMock(RegionWidgetRepository.class);
         pageLayoutRepository = createMock(PageLayoutRepository.class);
         userService = createMock(UserService.class);
         pageService = new DefaultPageService(pageRepository, regionRepository, widgetRepository, regionWidgetRepository, pageLayoutRepository, userService, defaultPageName);
@@ -105,9 +105,12 @@ public class PageServiceTest {
         pageLayout.setNumberOfRegions(3L);
         
         page = new Page(PAGE_ID, user);
+        page.setRenderSequence(1L);
+        page2 = new Page(99L, user);
+        page2.setRenderSequence(2L);
         
         pageList = new ArrayList<Page>();        
-        pageList.add(new Page(99L));
+        pageList.add(page2);
         pageList.add(page);
     }
 
@@ -216,9 +219,16 @@ public class PageServiceTest {
     }
   
     @Test
-    public void deletePage() {               
+    public void deletePage() {
+        List<Page> pageListAfterDelete = new ArrayList<Page>(pageList);
+        pageListAfterDelete.remove(page);
+        
         expect(userService.getAuthenticatedUser()).andReturn(user);
         expect(pageRepository.get(PAGE_ID)).andReturn(page);
+        pageRepository.delete(page);
+        expectLastCall();
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageListAfterDelete);
+        expect(pageRepository.save(page2)).andReturn(page2);
         replay(userService);
         replay(pageRepository);
         pageService.deletePage(PAGE_ID);
@@ -232,6 +242,11 @@ public class PageServiceTest {
         
         expect(userService.getAuthenticatedUser()).andReturn(user);
         expect(pageRepository.get(INVALID_PAGE_ID)).andReturn(page);
+        pageRepository.delete(page);
+        expectLastCall();
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageList);
+        expect(pageRepository.save(page2)).andReturn(page2);
+        expect(pageRepository.save(page)).andReturn(page);
         replay(userService);
         replay(pageRepository);
         pageService.deletePage(INVALID_PAGE_ID);
@@ -318,14 +333,12 @@ public class PageServiceTest {
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void moveRegionWidget_invalidTarget() {
-        createMoveBetweenRegionsExpectations();
+    public void moveRegionWidget_invalidTarget() {       
         pageService.moveRegionWidget(-1L, 0, 5L, 6L);
     }
 
     @Test(expected = IllegalArgumentException.class)
-    public void moveRegionWidget_invalidTarget_sameRegion() {
-        createMoveBetweenRegionsExpectations();
+    public void moveRegionWidget_invalidTarget_sameRegion() {       
         pageService.moveRegionWidget(-1L, 0, 5L, 5L);
     }
 
@@ -432,7 +445,72 @@ public class PageServiceTest {
     public void getPageFromList_invalidId() {
         assertThat(pageService.getPageFromList(INVALID_PAGE_ID, pageList), is(nullValue(Page.class)));
     }
+        
+    @Test
+    public void movePage() {               
+        expect(userService.getAuthenticatedUser()).andReturn(user);
+        expect(pageRepository.get(PAGE_ID)).andReturn(page);
+        expect(pageRepository.get(page2.getId())).andReturn(page2);
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageList);        
+        expect(pageRepository.save(page2)).andReturn(page2);
+        expect(pageRepository.save(page)).andReturn(page);        
+        replay(userService);
+        replay(pageRepository);
+                          
+        assertThat(pageService.movePage(PAGE_ID, page2.getId()).getRenderSequence(), is(2L));
+        assertThat(page2.getRenderSequence(), is(1L));        
+      
+        verify(userService);        
+        verify(pageRepository);
+    }
+    
+    @Test(expected=RuntimeException.class)
+    public void movePage_invalidPageId() {               
+        expect(userService.getAuthenticatedUser()).andReturn(user);
+        expect(pageRepository.get(INVALID_PAGE_ID)).andReturn(null);
+        expect(pageRepository.get(page2.getId())).andReturn(page2);
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageList);               
+        replay(userService);
+        replay(pageRepository);
+                          
+        pageService.movePage(INVALID_PAGE_ID, page2.getId());      
+      
+        verify(userService);        
+        verify(pageRepository);
+    }    
+  
+    @Test
+    public void movePageToDefault() {               
+        expect(userService.getAuthenticatedUser()).andReturn(user);
+        expect(pageRepository.get(page2.getId())).andReturn(page2);
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageList);        
+        expect(pageRepository.save(page)).andReturn(page);
+        expect(pageRepository.save(page2)).andReturn(page2);        
+        replay(userService);
+        replay(pageRepository);
+                          
+        assertThat(pageService.movePageToDefault(page2.getId()).getRenderSequence(), is(1L));
+        assertThat(page.getRenderSequence(), is(2L));        
+      
+        verify(userService);        
+        verify(pageRepository);
+    }    
+    
+    @Test(expected=RuntimeException.class)
+    public void movePageToDefault_invalidPageId() {               
+        expect(userService.getAuthenticatedUser()).andReturn(user);
+        expect(pageRepository.get(INVALID_PAGE_ID)).andReturn(null);
+        expect(pageRepository.getAllPages(user.getId())).andReturn(pageList);              
+        replay(userService);
+        replay(pageRepository);
+                          
+        pageService.movePageToDefault(INVALID_PAGE_ID);     
+      
+        verify(userService);        
+        verify(pageRepository);
+    }       
     
+    // private methods    
     private void verifyPositions(int newPosition, RegionWidget widget, boolean sameRegion) {
         assertThat(widget.getRenderOrder(), is(equalTo(newPosition)));        
         assertOrder(originalRegion);

Modified: incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java (original)
+++ incubator/rave/trunk/rave-portal/src/test/java/org/apache/rave/portal/web/api/rpc/PageApiTest.java Thu Aug 25 21:00:40 2011
@@ -34,18 +34,25 @@ import static org.junit.Assert.assertTha
 /** */
 public class PageApiTest {
 
-    private static final String PARAM_ERROR_MESSAGE = "Target Region does not exist";
-    private static final String INTERNAL_ERROR_MESSAGE = "Internal Error";
+    private final String PARAM_ERROR_MESSAGE = "Target Region does not exist";
+    private final String INTERNAL_ERROR_MESSAGE = "Internal Error";
     private PageApi pageApi;
     private PageService pageService;
-    private static final long REGION_WIDGET_ID = 35;
-    private static final int NEW_POSITION = 3;
+    private final long REGION_WIDGET_ID = 35;
+    private final int NEW_POSITION = 3;
+    private final long PAGE_ID = 20L;
+    private final long PAGE_2_ID = 38L;
+    
+    private Page page, page2;
 
 
     @Before
     public void setup() {
         pageService = createMock(PageService.class);
         pageApi = new PageApi(pageService);
+        
+        page = new Page(PAGE_ID);
+        page2 = new Page(PAGE_2_ID);
     }
 
     @Test
@@ -237,4 +244,34 @@ public class PageApiTest {
         assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.INTERNAL_ERROR));
         assertThat(result.getErrorMessage(), is(equalTo(INTERNAL_ERROR_MESSAGE)));
     }
+    
+    @Test
+    public void movePage_nonNullMoveAfterPageId() {
+        expect(pageService.movePage(PAGE_ID, PAGE_2_ID)).andReturn(page);
+        replay(pageService);
+                
+        RpcResult result = pageApi.movePage(PAGE_ID, PAGE_2_ID);                
+        
+        verify(pageService);        
+        assertThat(result, is(notNullValue()));
+        assertThat((Page)result.getResult(), is(page));
+        assertThat(result.isError(), is(false));
+        assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));
+        assertThat(result.getErrorMessage(), is(nullValue()));
+    }    
+    
+    @Test
+    public void movePage_nullMoveAfterPageId() {
+        expect(pageService.movePageToDefault(PAGE_2_ID)).andReturn(page2);
+        replay(pageService);
+                
+        RpcResult result = pageApi.movePage(PAGE_2_ID, null);                
+        
+        verify(pageService);        
+        assertThat(result, is(notNullValue()));
+        assertThat((Page)result.getResult(), is(page2));
+        assertThat(result.isError(), is(false));
+        assertThat(result.getErrorCode(), is(RpcResult.ErrorCode.NO_ERROR));
+        assertThat(result.getErrorMessage(), is(nullValue()));
+    }      
 }

Modified: incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js
URL: http://svn.apache.org/viewvc/incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js?rev=1161760&r1=1161759&r2=1161760&view=diff
==============================================================================
--- incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js (original)
+++ incubator/rave/trunk/rave-portal/src/test/javascript/raveApiSpec.js Thu Aug 25 21:00:40 2011
@@ -187,6 +187,24 @@ describe("Rave API", function() {
                 rave.api.rpc.addPage({pageName: newPageName, pageLayoutCode: newPageLayoutCode});
             });
         });
+        
+        describe("movePage", function() {
+            it("posts the correct values to RPC service for moving a page", function() {
+                var pageId = 7;
+                var moveAfterPageId = 29;
+
+                $.post = function(url, data, callback) {
+                    expect(url).toEqual("api/rpc/page/" + pageId + "/move");                   
+                    expect(data.moveAfterPageId).toEqual(moveAfterPageId);
+                    expect(typeof(callback)).toEqual("function");
+                    return {
+                        error: function(a, b, c) {
+                        }
+                    }
+                };
+                rave.api.rpc.movePage({pageId: pageId, moveAfterPageId: moveAfterPageId});
+            });
+        });        
 
         describe("Error handling", function() {
             it("displays the appropriate alert when invalid parameters are passed", function() {