1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 package org.mozilla.gecko.activitystream.homepanel.topstories; 6 7 import junit.framework.Assert; 8 import org.json.JSONArray; 9 import org.json.JSONException; 10 import org.json.JSONObject; 11 import org.junit.Test; 12 import org.junit.runner.RunWith; 13 import org.mozilla.gecko.activitystream.homepanel.model.TopStory; 14 import org.mozilla.gecko.background.testhelpers.TestRunner; 15 16 import java.util.List; 17 18 @RunWith(TestRunner.class) 19 public class TestPocketStoriesLoader { 20 private static final String KEY_STATUS = "status"; 21 private static final String KEY_LIST = "list"; 22 23 private static final String KEY_URL = "url"; 24 private static final String KEY_DEDUPE_URL = "dedupe_url"; 25 private static final String KEY_TITLE = "title"; 26 private static final String KEY_IMAGE_SRC = "image_src"; 27 28 private static final String POCKET_URL = "POCKET_URL"; 29 private static final String PAGE_URL = "PAGE_URL"; 30 private static final String TITLE = "TITLE"; 31 private static final String IMAGE_URL = "IMAGE_URL"; 32 makeBasicPocketResponse(JSONObject[] storyItems)33 private String makeBasicPocketResponse(JSONObject[] storyItems) { 34 final JSONObject basicResponse = new JSONObject(); 35 try { 36 final JSONArray array = new JSONArray(); 37 for (JSONObject item : storyItems) { 38 array.put(item); 39 } 40 41 basicResponse.put(KEY_STATUS, 1); // arbitrarily chosen 42 basicResponse.put(KEY_LIST, array); 43 44 } catch (JSONException e) { 45 Assert.fail("Problem creating Pocket response JSON object"); 46 } 47 return basicResponse.toString(); 48 } 49 makeBasicStoryItem()50 private JSONObject makeBasicStoryItem() { 51 final JSONObject storyItem = new JSONObject(); 52 try { 53 storyItem.put(KEY_URL, POCKET_URL); 54 storyItem.put(KEY_DEDUPE_URL, PAGE_URL); 55 storyItem.put(KEY_TITLE, TITLE); 56 storyItem.put(KEY_IMAGE_SRC, IMAGE_URL); 57 } catch (JSONException e) { 58 Assert.fail("Problem creating Pocket story JSON object"); 59 } 60 return storyItem; 61 } 62 63 @Test testJSONStringToTopStoriesWithBasicObject()64 public void testJSONStringToTopStoriesWithBasicObject() { 65 final String basicResponseString = makeBasicPocketResponse(new JSONObject[] { makeBasicStoryItem() }); 66 final List<TopStory> stories = PocketStoriesLoader.jsonStringToTopStories(basicResponseString); 67 Assert.assertEquals(1, stories.size()); 68 69 final TopStory story = stories.get(0); 70 Assert.assertEquals(PAGE_URL, story.getUrl()); 71 Assert.assertEquals(TITLE, story.getTitle()); 72 Assert.assertEquals(IMAGE_URL, story.getImageUrl()); 73 } 74 75 @Test testJSONStringToTopStoriesWithMissingTitle()76 public void testJSONStringToTopStoriesWithMissingTitle() { 77 final JSONObject storyItem = makeBasicStoryItem(); 78 storyItem.remove(KEY_TITLE); 79 final String malformedResponseString = makeBasicPocketResponse(new JSONObject[] { storyItem }); 80 final List<TopStory> stories = PocketStoriesLoader.jsonStringToTopStories(malformedResponseString); 81 Assert.assertEquals(0, stories.size()); // Should skip malformed item. 82 } 83 84 @Test testJSONStringToTopStoriesDropsMalformedTitle()85 public void testJSONStringToTopStoriesDropsMalformedTitle() throws Exception { 86 final JSONObject malformedStory = makeBasicStoryItem(); 87 malformedStory.put(KEY_TITLE, ""); 88 assertJSONStringToTopStoriesDropsMalformedStory(malformedStory); 89 } 90 91 @Test testJSONStringToTopStoriesDropsMalformedURL()92 public void testJSONStringToTopStoriesDropsMalformedURL() throws Exception { 93 final JSONObject malformedStory = makeBasicStoryItem(); 94 malformedStory.put(KEY_DEDUPE_URL, ""); 95 assertJSONStringToTopStoriesDropsMalformedStory(malformedStory); 96 } 97 98 @Test testJSONStringToTopStoriesDropsMalformedImageURL()99 public void testJSONStringToTopStoriesDropsMalformedImageURL() throws Exception { 100 final JSONObject malformedStory = makeBasicStoryItem(); 101 malformedStory.put(KEY_IMAGE_SRC, ""); 102 assertJSONStringToTopStoriesDropsMalformedStory(malformedStory); 103 } 104 assertJSONStringToTopStoriesDropsMalformedStory(final JSONObject malformedStory)105 private void assertJSONStringToTopStoriesDropsMalformedStory(final JSONObject malformedStory) throws JSONException { 106 final JSONObject expectedStory = makeBasicStoryItem(); 107 final String expectedStoryTitle = "expectedItem"; 108 expectedStory.put(KEY_TITLE, expectedStoryTitle); 109 110 final String jsonResponse = makeBasicPocketResponse(new JSONObject[] { expectedStory, malformedStory }); 111 final List<TopStory> actualTopStories = PocketStoriesLoader.jsonStringToTopStories(jsonResponse); 112 113 Assert.assertEquals("Expected one malformed item to be removed, leaving size 1", 1, actualTopStories.size()); 114 Assert.assertEquals(expectedStoryTitle, actualTopStories.get(0).getTitle()); 115 } 116 117 // Pulled 8/28 Pocket response, with some trimming for content/brevity. 118 final String VALID_POCKET_RESPONSE = "{\"status\":1,\"list\":[" + 119 "{\"id\":2910,\"url\":\"https:\\/\\/pocket.co\\/pocket-shorted-url\"," + 120 "\"dedupe_url\":\"http:\\/\\/www.bbc.co.uk\\/actual-url\"," + 121 "\"title\":\"A Title Here\"," + 122 "\"excerpt\":\"Middle-aged people are being urged...\"," + 123 "\"domain\":\"bbc.co.uk\"," + 124 "\"image_src\":\"https:\\/\\/img.cloudfront.net\"," + 125 "\"published_timestamp\":\"1503550800\",\"sort_id\":0}," + 126 127 "{\"id\":2909,\"url\":\"https:\\/\\/pocket.co\\/00000\"," + 128 "\"dedupe_url\":\"http:\\/\\/fortune.com\"," + 129 "\"title\":\"The Mattress Industry\",\"excerpt\":\"In any random commute...\"," + 130 "\"domain\":\"fortune.com\",\"image_src\":\"https:\\/\\/d33ypg4xwx0n86.cloudfront.net\"," + 131 "\"published_timestamp\":\"1503464400\",\"sort_id\":1}," + 132 133 "{\"id\":2908,\"url\":\"https:\\/\\/pocket.co\\/00000\"," + 134 "\"dedupe_url\":\"https:\\/\\/medium.com\",\"title\":\"Mediocrity is a Virus.\"," + 135 "\"excerpt\":\"Little things become big things.\",\"domain\":\"medium.com\"," + 136 "\"image_src\":\"https:\\/\\/d33ypg4xwx0n86.cloudfront.net\",\"published_timestamp\":\"1503578016\",\"sort_id\":2}]}"; 137 138 @Test testJSONStringToTopStoriesWithPocketServerResponse()139 public void testJSONStringToTopStoriesWithPocketServerResponse() { 140 final List<TopStory> stories = PocketStoriesLoader.jsonStringToTopStories(VALID_POCKET_RESPONSE); 141 Assert.assertEquals(3, stories.size()); 142 final TopStory story = stories.get(0); 143 144 Assert.assertEquals("http://www.bbc.co.uk/actual-url", story.getUrl()); 145 Assert.assertEquals("A Title Here", story.getTitle()); 146 Assert.assertEquals("https://img.cloudfront.net", story.getImageUrl()); 147 } 148 }