1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.neo4j.examples.socnet;
20
21 import static org.hamcrest.CoreMatchers.equalTo;
22 import static org.hamcrest.collection.IsCollectionContaining.hasItems;
23 import static org.junit.Assert.assertThat;
24
25 import java.util.ArrayList;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.Random;
29
30 import org.hamcrest.CoreMatchers;
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.neo4j.graphdb.GraphDatabaseService;
35 import org.neo4j.graphdb.Node;
36 import org.neo4j.graphdb.index.Index;
37 import org.neo4j.helpers.collection.IteratorUtil;
38 import org.neo4j.kernel.EmbeddedGraphDatabase;
39
40 public class SocnetTest
41 {
42 private static final Random r = new Random( System.currentTimeMillis() );
43 private GraphDatabaseService graphDb;
44 private Index<Node> index;
45 private PersonRepository personRepository;
46 private int nrOfPersons;
47
48 @Before
49 public void setup() throws Exception
50 {
51 graphDb = new EmbeddedGraphDatabase( "target/socnetdb" );
52 index = graphDb.index().forNodes( "nodes" );
53 personRepository = new PersonRepository( graphDb, index );
54 deleteSocialGraph();
55
56 nrOfPersons = 20;
57 createPersons();
58 setupFriendsBetweenPeople( 10 );
59 }
60
61 @After
62 public void teardown()
63 {
64 try
65 {
66 deleteSocialGraph();
67 }
68 finally
69 {
70 graphDb.shutdown();
71 }
72 }
73
74 @Test
75 public void addStatusAndRetrieveIt() throws Exception
76 {
77 Person person = getRandomPerson();
78 person.addStatus( "Testing!" );
79
80 StatusUpdate update = person.getStatus().iterator().next();
81
82 assertThat( update, CoreMatchers.<Object>notNullValue() );
83 assertThat( update.getStatusText(), equalTo( "Testing!" ) );
84 assertThat( update.getPerson(), equalTo( person ) );
85 }
86
87 @Test
88 public void multipleStatusesComeOutInTheRightOrder() throws Exception
89 {
90 ArrayList<String> statuses = new ArrayList<String>();
91 statuses.add( "Test1" );
92 statuses.add( "Test2" );
93 statuses.add( "Test3" );
94
95 Person person = getRandomPerson();
96 for ( String status : statuses )
97 {
98 person.addStatus( status );
99 }
100
101 int i = statuses.size();
102 for ( StatusUpdate update : person.getStatus() )
103 {
104 i--;
105 assertThat( update.getStatusText(), equalTo( statuses.get( i ) ) );
106 }
107 }
108
109 @Test
110 public void removingOneFriendIsHandledCleanly()
111 {
112 Person person1 = personRepository.getPersonByName( "person#1" );
113 Person person2 = personRepository.getPersonByName( "person#2" );
114 person1.addFriend( person2 );
115
116 int noOfFriends = person1.getNrOfFriends();
117
118 person1.removeFriend( person2 );
119
120 int noOfFriendsAfterChange = person1.getNrOfFriends();
121
122 assertThat( noOfFriends, equalTo( noOfFriendsAfterChange + 1 ) );
123 }
124
125 @Test
126 public void retrieveStatusUpdatesInDateOrder() throws Exception
127 {
128 Person person = getRandomPersonWithFriends();
129 int numberOfStatuses = 20;
130
131 for ( int i = 0; i < numberOfStatuses; i++ )
132 {
133 Person friend = getRandomFriendOf( person );
134 friend.addStatus( "Dum-deli-dum..." );
135 }
136
137 ArrayList<StatusUpdate> updates = fromIterableToArrayList( person.friendStatuses() );
138 assertThat( updates.size(), equalTo( numberOfStatuses ) );
139 assertUpdatesAreSortedByDate( updates );
140 }
141
142 @Test
143 public void friendsOfFriendsWorks() throws Exception
144 {
145 Person person = getRandomPerson();
146 Person friend = getRandomFriendOf( person );
147
148 for ( Person friendOfFriend : friend.getFriends() )
149 {
150 if ( !friendOfFriend.equals( person ) )
151 {
152 assertThat( person.getFriendsOfFriends(), hasItems( friendOfFriend ) );
153 }
154 }
155 }
156
157 @Test
158 public void shouldReturnTheCorrectPersonFromAnyStatusUpdate() throws Exception
159 {
160 Person person = getRandomPerson();
161 person.addStatus( "Foo" );
162 person.addStatus( "Bar" );
163 person.addStatus( "Baz" );
164
165 for(StatusUpdate status : person.getStatus())
166 {
167 assertThat(status.getPerson(), equalTo( person ));
168 }
169 }
170
171 @Test
172 public void getPathBetweenFriends() throws Exception
173 {
174 deleteSocialGraph();
175 Person start = personRepository.createPerson( "start" );
176 Person middleMan1 = personRepository.createPerson( "middle1" );
177 Person middleMan2 = personRepository.createPerson( "middle2" );
178 Person endMan = personRepository.createPerson( "endMan" );
179
180
181
182 start.addFriend( middleMan1 );
183 middleMan1.addFriend( middleMan2 );
184 middleMan2.addFriend( endMan );
185
186 Iterable<Person> path = start.getShortestPathTo( endMan, 4 );
187
188 assertPathIs( path, start, middleMan1, middleMan2, endMan );
189
190 }
191
192 @Test
193 public void singleFriendRecommendation() throws Exception
194 {
195 deleteSocialGraph();
196 Person a = personRepository.createPerson( "a" );
197 Person b = personRepository.createPerson( "b" );
198 Person c = personRepository.createPerson( "c" );
199 Person d = personRepository.createPerson( "d" );
200 Person e = personRepository.createPerson( "e" );
201
202
203 a.addFriend( b );
204 a.addFriend( c );
205 a.addFriend( d );
206
207
208 e.addFriend( b );
209 e.addFriend( c );
210 e.addFriend( d );
211
212 Person recommendation = IteratorUtil.single( a.getFriendRecommendation( 1 ).iterator() );
213
214 assertThat( recommendation, equalTo( e ) );
215 }
216
217 @Test
218 public void weightedFriendRecommendation() throws Exception
219 {
220 deleteSocialGraph();
221 Person a = personRepository.createPerson( "a" );
222 Person b = personRepository.createPerson( "b" );
223 Person c = personRepository.createPerson( "c" );
224 Person d = personRepository.createPerson( "d" );
225 Person e = personRepository.createPerson( "e" );
226 Person f = personRepository.createPerson( "f" );
227
228
229
230 a.addFriend( b );
231 a.addFriend( c );
232 a.addFriend( d );
233
234
235 e.addFriend( b );
236
237
238 f.addFriend( b );
239 f.addFriend( c );
240 f.addFriend( d );
241
242 ArrayList<Person> recommendations = fromIterableToArrayList( a.getFriendRecommendation( 2 ).iterator() );
243
244 assertThat( recommendations.get( 0 ), equalTo( f ));
245 assertThat( recommendations.get( 1 ), equalTo( e ));
246 }
247
248 private <T> ArrayList<T> fromIterableToArrayList( Iterator<T> iterable )
249 {
250 ArrayList<T> collection = new ArrayList<T>();
251 IteratorUtil.addToCollection( iterable, collection );
252 return collection;
253 }
254
255 private void assertPathIs( Iterable<Person> path,
256 Person... expectedPath )
257 {
258 ArrayList<Person> pathArray = new ArrayList<Person>();
259 IteratorUtil.addToCollection( path, pathArray );
260 assertThat( pathArray.size(), equalTo( expectedPath.length ) );
261 for ( int i = 0; i < expectedPath.length; i++ )
262 {
263 assertThat( pathArray.get( i ), equalTo( expectedPath[ i ] ) );
264 }
265 }
266
267 private void setupFriendsBetweenPeople( int maxNrOfFriendsEach )
268 {
269 for ( Person person : personRepository.getAllPersons() )
270 {
271 int nrOfFriends = r.nextInt( maxNrOfFriendsEach ) + 1;
272 for ( int j = 0; j < nrOfFriends; j++ )
273 {
274 person.addFriend( getRandomPerson() );
275 }
276 }
277 }
278
279 private Person getRandomPerson()
280 {
281 return personRepository.getPersonByName( "person#"
282 + r.nextInt( nrOfPersons ) );
283 }
284
285 private void deleteSocialGraph()
286 {
287 for ( Person person : personRepository.getAllPersons() )
288 {
289 personRepository.deletePerson( person );
290 }
291 }
292
293 private Person getRandomFriendOf( Person p )
294 {
295 ArrayList<Person> friends = new ArrayList<Person>();
296 IteratorUtil.addToCollection( p.getFriends().iterator(), friends );
297 return friends.get( r.nextInt( friends.size() ) );
298 }
299
300 private Person getRandomPersonWithFriends()
301 {
302 Person p;
303 do
304 {
305 p = getRandomPerson();
306 }
307 while ( p.getNrOfFriends() == 0 );
308 return p;
309 }
310
311 private void createPersons() throws Exception
312 {
313 for ( int i = 0; i < nrOfPersons; i++ )
314 {
315 personRepository.createPerson( "person#" + i );
316 }
317 }
318
319 private void assertUpdatesAreSortedByDate(
320 ArrayList<StatusUpdate> statusUpdates )
321 {
322 Date date = new Date( 0 );
323 for ( StatusUpdate update : statusUpdates )
324 {
325 org.junit.Assert.assertTrue( date.getTime() < update.getDate().getTime() );
326
327 }
328 }
329 }