/* * Copyright (C) 2009 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.sites.liberation.export; import static org.junit.Assert.*; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.gdata.client.sites.SitesService; import com.google.gdata.data.ILink; import com.google.gdata.data.PlainTextConstruct; import com.google.gdata.data.XhtmlTextConstruct; import com.google.gdata.data.sites.AttachmentEntry; import com.google.gdata.data.sites.BaseContentEntry; import com.google.gdata.data.sites.BasePageEntry; import com.google.gdata.data.sites.FileCabinetPageEntry; import com.google.gdata.data.sites.ListPageEntry; import com.google.gdata.data.sites.PageName; import com.google.gdata.data.sites.SitesLink; import com.google.gdata.data.sites.WebPageEntry; import com.google.gdata.util.XmlBlob; import com.google.sites.liberation.util.ProgressListener; import org.junit.Before; import org.junit.Test; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JUnit4Mockery; import org.jmock.lib.legacy.ClassImposteriser; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.Collection; import java.util.Map; /** * @author bsimon@google.com (Benjamin Simon) */ public class SiteExporterImplTest { private Mockery context; private AbsoluteLinkConverter linkConverter; private AppendableFactory appendableFactory; private AttachmentDownloader attachmentDownloader; private EntryStore entryStore; private EntryStoreFactory entryStoreFactory; private FeedProvider feedProvider; private PageExporter pageExporter; private ProgressListener progressListener; private RevisionsExporter revisionsExporter; private SiteExporter siteExporter; private SitesService sitesService; private Collection<BaseContentEntry<?>> entries; private URL feedUrl; private Map<AttachmentEntry, File> downloaded; @Before public void before() throws MalformedURLException { context = new JUnit4Mockery() {{ setImposteriser(ClassImposteriser.INSTANCE); }}; linkConverter = context.mock(AbsoluteLinkConverter.class); appendableFactory = context.mock(AppendableFactory.class); attachmentDownloader = new FakeDownloader(); entryStore = context.mock(EntryStore.class); entryStoreFactory = context.mock(EntryStoreFactory.class); feedProvider = context.mock(FeedProvider.class); pageExporter = context.mock(PageExporter.class); progressListener = context.mock(ProgressListener.class); revisionsExporter = context.mock(RevisionsExporter.class); siteExporter = new SiteExporterImpl(linkConverter, appendableFactory, attachmentDownloader, entryStoreFactory, feedProvider, pageExporter, revisionsExporter); sitesService = new SitesService(""); entries = Sets.newHashSet(); feedUrl = new URL("https://host/feeds/content/domain/webspace"); } @Test public void testEmptyExport() { context.checking(new Expectations() {{ allowing (entryStoreFactory).newEntryStore(); will(returnValue(entryStore)); allowing (progressListener).setStatus(with(any(String.class))); allowing (feedProvider).getEntries(feedUrl, sitesService); will(returnValue(entries)); }}); export(false); } @Test public void testOnePage() throws IOException { final BasePageEntry<?> page = new WebPageEntry(); page.setId("1"); page.setTitle(new PlainTextConstruct("Page 1")); page.setPageName(new PageName("Page-1")); XmlBlob blob = new XmlBlob(); blob.setBlob("content"); page.setContent(new XhtmlTextConstruct(blob)); entries.add(page); final Appendable out = context.mock(Appendable.class); context.checking(new Expectations() {{ allowing (entryStoreFactory).newEntryStore(); will(returnValue(entryStore)); allowing (feedProvider).getEntries(feedUrl, sitesService); will(returnValue(entries)); allowing (entryStore).getEntry("1"); will(returnValue(page)); allowing (entryStore).getParent("1"); will(returnValue(null)); allowing (progressListener).setStatus(with(any(String.class))); allowing (progressListener).setProgress(with(any(Double.class))); oneOf (entryStore).addEntry(page); oneOf (appendableFactory).getAppendable( new File("path/Page-1/index.html")); will(returnValue(out)); oneOf (linkConverter).convertLinks(page, entryStore, new URL("https://host/a/domain/webspace"), false); oneOf (pageExporter).exportPage(page, entryStore, out, true); oneOf (revisionsExporter).exportRevisions(page, entryStore, new File("path/Page-1"), sitesService, new URL("https://host/a/domain/webspace")); }}); export(true); } @Test public void testOnePageWithAttachment() throws IOException { final BasePageEntry<?> page = new FileCabinetPageEntry(); page.setId("1"); page.setTitle(new PlainTextConstruct("Page 1")); page.setPageName(new PageName("Page-1")); XmlBlob blob = new XmlBlob(); blob.setBlob("content"); page.setContent(new XhtmlTextConstruct(blob)); final BaseContentEntry<?> attachment = new AttachmentEntry(); attachment.setId("2"); attachment.setTitle(new PlainTextConstruct("attach this.wow")); attachment.addLink(SitesLink.Rel.PARENT, ILink.Type.ATOM, "1"); entries.add(page); entries.add(attachment); final Appendable out = context.mock(Appendable.class); context.checking(new Expectations() {{ allowing (entryStoreFactory).newEntryStore(); will(returnValue(entryStore)); allowing (feedProvider).getEntries(feedUrl, sitesService); will(returnValue(entries)); allowing (entryStore).getEntry("1"); will(returnValue(page)); allowing (entryStore).getParent("1"); will(returnValue(null)); allowing (entryStore).getEntry("2"); will(returnValue(attachment)); allowing (entryStore).getParent("2"); will(returnValue(page)); allowing (progressListener).setStatus(with(any(String.class))); allowing (progressListener).setProgress(with(any(Double.class))); oneOf (entryStore).addEntry(page); oneOf (entryStore).addEntry(attachment); oneOf (appendableFactory).getAppendable( new File("path/Page-1/index.html")); will(returnValue(out)); oneOf (linkConverter).convertLinks(page, entryStore, new URL("https://host/a/domain/webspace"), false); oneOf (pageExporter).exportPage(page, entryStore, out, false); }}); export(false); assertTrue(downloaded.get(attachment).equals( new File("path/Page-1/attach this.wow"))); } @Test public void testSeveralOfEach() throws IOException { final BasePageEntry<?> page1 = new WebPageEntry(); page1.setId("1"); page1.setTitle(new PlainTextConstruct("Page 1")); page1.setPageName(new PageName("Page-1")); XmlBlob blob = new XmlBlob(); blob.setBlob("content"); page1.setContent(new XhtmlTextConstruct(blob)); final BaseContentEntry<?> attachment1 = new AttachmentEntry(); attachment1.setId("2"); attachment1.setTitle(new PlainTextConstruct("attach this.wow")); attachment1.addLink(SitesLink.Rel.PARENT, ILink.Type.ATOM, "1"); final BasePageEntry<?> page2 = new ListPageEntry(); page2.setId("3"); page2.setTitle(new PlainTextConstruct("Page 2")); page2.setPageName(new PageName("Page-2")); page2.setContent(new XhtmlTextConstruct(blob)); page2.addLink(SitesLink.Rel.PARENT, ILink.Type.ATOM, "1"); final BaseContentEntry<?> attachment2 = new AttachmentEntry(); attachment2.setId("4"); attachment2.setTitle(new PlainTextConstruct("picture.png")); attachment2.addLink(SitesLink.Rel.PARENT, ILink.Type.ATOM, "1"); final BaseContentEntry<?> attachment3 = new AttachmentEntry(); attachment3.setId("5"); attachment3.setTitle(new PlainTextConstruct("document.doc")); attachment3.addLink(SitesLink.Rel.PARENT, ILink.Type.ATOM, "3"); entries.add(page1); entries.add(attachment1); entries.add(page2); entries.add(attachment2); entries.add(attachment3); final Appendable out1 = context.mock(Appendable.class, "out1"); final Appendable out2 = context.mock(Appendable.class, "out2"); context.checking(new Expectations() {{ allowing (entryStoreFactory).newEntryStore(); will(returnValue(entryStore)); allowing (feedProvider).getEntries(feedUrl, sitesService); will(returnValue(entries)); allowing (entryStore).getEntry("1"); will(returnValue(page1)); allowing (entryStore).getEntry("2"); will(returnValue(attachment1)); allowing (entryStore).getEntry("3"); will(returnValue(page2)); allowing (entryStore).getEntry("4"); will(returnValue(attachment2)); allowing (entryStore).getEntry("5"); will(returnValue(attachment3)); allowing (entryStore).getParent("1"); will(returnValue(null)); allowing (entryStore).getParent("2"); will(returnValue(page1)); allowing (entryStore).getParent("3"); will(returnValue(page1)); allowing (entryStore).getParent("4"); will(returnValue(page1)); allowing (entryStore).getParent("5"); will(returnValue(page2)); allowing (progressListener).setStatus(with(any(String.class))); allowing (progressListener).setProgress(with(any(Double.class))); oneOf (entryStore).addEntry(page1); oneOf (entryStore).addEntry(attachment1); oneOf (entryStore).addEntry(page2); oneOf (entryStore).addEntry(attachment2); oneOf (entryStore).addEntry(attachment3); oneOf (appendableFactory).getAppendable( new File("path/Page-1/index.html")); will(returnValue(out1)); oneOf (appendableFactory).getAppendable( new File("path/Page-1/Page-2/index.html")); will(returnValue(out2)); oneOf (linkConverter).convertLinks(page1, entryStore, new URL("https://host/a/domain/webspace"), false); oneOf (linkConverter).convertLinks(page2, entryStore, new URL("https://host/a/domain/webspace"), false); oneOf (pageExporter).exportPage(page1, entryStore, out1, true); oneOf (pageExporter).exportPage(page2, entryStore, out2, true); oneOf (revisionsExporter).exportRevisions(page1, entryStore, new File("path/Page-1"), sitesService, new URL("https://host/a/domain/webspace")); oneOf (revisionsExporter).exportRevisions(page2, entryStore, new File("path/Page-1/Page-2"), sitesService, new URL("https://host/a/domain/webspace")); }}); export(true); assertTrue(downloaded.get(attachment1).equals( new File("path/Page-1/attach this.wow"))); assertTrue(downloaded.get(attachment2).equals( new File("path/Page-1/picture.png"))); assertTrue(downloaded.get(attachment3).equals( new File("path/Page-1/Page-2/document.doc"))); } private void export(boolean exportRevisions) { siteExporter.exportSite("host", "domain", "webspace", exportRevisions, sitesService, new File("path"), progressListener); } /** * This class was needed because mocking the AttachmentDownloader with JMock * kept non-sensically failing (Greg agreed). */ private class FakeDownloader implements AttachmentDownloader { FakeDownloader() { downloaded = Maps.newHashMap(); } @Override public void download(AttachmentEntry attachment, File file, SitesService sitesService) { downloaded.put(attachment, file); } } }