Compare commits
8 Commits
725-result
...
384-conver
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b3722ad840 | ||
|
|
a6de1f7144 | ||
|
|
2698e4c181 | ||
|
|
db52b2c29f | ||
|
|
f750280845 | ||
|
|
1e8784efe9 | ||
|
|
7a3bd86522 | ||
|
|
c333052396 |
8
.idea/codeStyleSettings.xml
generated
@@ -31,8 +31,6 @@
|
|||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
<option name="RIGHT_MARGIN" value="100" />
|
<option name="RIGHT_MARGIN" value="100" />
|
||||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
|
|
||||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
|
|
||||||
<AndroidXmlCodeStyleSettings>
|
<AndroidXmlCodeStyleSettings>
|
||||||
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
<option name="USE_CUSTOM_SETTINGS" value="true" />
|
||||||
</AndroidXmlCodeStyleSettings>
|
</AndroidXmlCodeStyleSettings>
|
||||||
@@ -70,12 +68,6 @@
|
|||||||
<XML>
|
<XML>
|
||||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||||
</XML>
|
</XML>
|
||||||
<codeStyleSettings language="Groovy">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
|
||||||
<option name="SMART_TABS" value="true" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="JAVA">
|
<codeStyleSettings language="JAVA">
|
||||||
<option name="RIGHT_MARGIN" value="80" />
|
<option name="RIGHT_MARGIN" value="80" />
|
||||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||||
|
|||||||
17
LICENSE.txt
@@ -13,6 +13,23 @@
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
All files under the directories briar-android/src, briar-api/src,
|
||||||
|
briar-core/src, briar-desktop/src and briar-test/src are licensed
|
||||||
|
under the Apache License, version 2.0 (the "License"); you may not
|
||||||
|
use these files 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.
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'witness'
|
||||||
apply plugin: 'com.neenbedankt.android-apt'
|
apply plugin: 'com.neenbedankt.android-apt'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
@@ -6,11 +7,20 @@ android {
|
|||||||
buildToolsVersion "23.0.3"
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 9
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
targetSdkVersion 22
|
||||||
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dexOptions {
|
||||||
|
incremental true
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_7
|
sourceCompatibility JavaVersion.VERSION_1_7
|
||||||
targetCompatibility JavaVersion.VERSION_1_7
|
targetCompatibility JavaVersion.VERSION_1_7
|
||||||
@@ -18,12 +28,23 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile project(':briar-api')
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
testCompile project(':briar-core')
|
compile project(':briar-api')
|
||||||
|
compile project(':briar-core')
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'net.jodah:concurrentunit:0.4.2'
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
testCompile 'com.android.support:appcompat-v7:23.2.1'
|
compile 'com.android.support:appcompat-v7:23.2.1'
|
||||||
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
provided 'javax.annotation:jsr250-api:1.0'
|
provided 'javax.annotation:jsr250-api:1.0'
|
||||||
testCompile project(':briar-tests')
|
testCompile project(':briar-tests')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencyVerification {
|
||||||
|
verify = [
|
||||||
|
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
||||||
|
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
||||||
|
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
|
||||||
|
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
|
||||||
|
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
17
briar-android-tests/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# By default, the flags in this file are appended to flags specified
|
||||||
|
# in /home/ernir/dev/sdk/tools/proguard/proguard-android.txt
|
||||||
|
# You can edit the include path and order by changing the proguardFiles
|
||||||
|
# directive in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# Add any project specific keep options here:
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
@@ -3,7 +3,6 @@ package org.briarproject;
|
|||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
import org.briarproject.api.blogs.Blog;
|
import org.briarproject.api.blogs.Blog;
|
||||||
import org.briarproject.api.blogs.BlogCommentHeader;
|
|
||||||
import org.briarproject.api.blogs.BlogFactory;
|
import org.briarproject.api.blogs.BlogFactory;
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
import org.briarproject.api.blogs.BlogManager;
|
||||||
import org.briarproject.api.blogs.BlogPost;
|
import org.briarproject.api.blogs.BlogPost;
|
||||||
@@ -12,6 +11,7 @@ import org.briarproject.api.blogs.BlogPostHeader;
|
|||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
import org.briarproject.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.api.crypto.KeyPair;
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
@@ -33,9 +33,7 @@ import org.briarproject.sync.SyncModule;
|
|||||||
import org.briarproject.transport.TransportModule;
|
import org.briarproject.transport.TransportModule;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -50,17 +48,15 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
import static junit.framework.Assert.assertFalse;
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
||||||
import static org.briarproject.api.blogs.MessageType.COMMENT;
|
|
||||||
import static org.briarproject.api.blogs.MessageType.POST;
|
|
||||||
import static org.briarproject.api.blogs.MessageType.WRAPPED_COMMENT;
|
|
||||||
import static org.briarproject.api.blogs.MessageType.WRAPPED_POST;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
||||||
|
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class BlogManagerTest extends BriarIntegrationTest {
|
public class BlogManagerTest {
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
||||||
private SyncSessionFactory sync0, sync1;
|
private SyncSessionFactory sync0, sync1;
|
||||||
@@ -91,15 +87,13 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
private final int TIMEOUT = 15000;
|
private final int TIMEOUT = 15000;
|
||||||
private final String AUTHOR1 = "Author 1";
|
private final String AUTHOR1 = "Author 1";
|
||||||
private final String AUTHOR2 = "Author 2";
|
private final String AUTHOR2 = "Author 2";
|
||||||
|
private final String CONTENT_TYPE = "text/plain";
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(BlogManagerTest.class.getName());
|
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
|
||||||
|
|
||||||
private BlogManagerTestComponent t0, t1;
|
private BlogManagerTestComponent t0, t1;
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BlogManagerTestComponent component =
|
BlogManagerTestComponent component =
|
||||||
@@ -173,15 +167,15 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
defaultInit();
|
defaultInit();
|
||||||
|
|
||||||
// check that blog0 has no posts
|
// check that blog0 has no posts
|
||||||
final String body = TestUtils.getRandomString(42);
|
final byte[] body = TestUtils.getRandomBytes(42);
|
||||||
Collection<BlogPostHeader> headers0 =
|
Collection<BlogPostHeader> headers0 =
|
||||||
blogManager0.getPostHeaders(blog0.getId());
|
blogManager0.getPostHeaders(blog0.getId());
|
||||||
assertEquals(0, headers0.size());
|
assertEquals(0, headers0.size());
|
||||||
|
|
||||||
// add a post to blog0
|
// add a post to blog0
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog0.getId(), null, clock.currentTimeMillis(),
|
||||||
author0, body);
|
null, author0, CONTENT_TYPE, body);
|
||||||
blogManager0.addLocalPost(p);
|
blogManager0.addLocalPost(p);
|
||||||
|
|
||||||
// check that post is now in blog0
|
// check that post is now in blog0
|
||||||
@@ -189,7 +183,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
assertEquals(1, headers0.size());
|
assertEquals(1, headers0.size());
|
||||||
|
|
||||||
// check that body is there
|
// check that body is there
|
||||||
assertEquals(body, blogManager0.getPostBody(p.getMessage().getId()));
|
assertArrayEquals(body,
|
||||||
|
blogManager0.getPostBody(p.getMessage().getId()));
|
||||||
|
|
||||||
// make sure that blog0 at author1 doesn't have the post yet
|
// make sure that blog0 at author1 doesn't have the post yet
|
||||||
Collection<BlogPostHeader> headers1 =
|
Collection<BlogPostHeader> headers1 =
|
||||||
@@ -203,10 +198,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
// make sure post arrived
|
// make sure post arrived
|
||||||
headers1 = blogManager1.getPostHeaders(blog0.getId());
|
headers1 = blogManager1.getPostHeaders(blog0.getId());
|
||||||
assertEquals(1, headers1.size());
|
assertEquals(1, headers1.size());
|
||||||
assertEquals(POST, headers1.iterator().next().getType());
|
|
||||||
|
|
||||||
// check that body is there
|
// check that body is there
|
||||||
assertEquals(body, blogManager1.getPostBody(p.getMessage().getId()));
|
assertArrayEquals(body,
|
||||||
|
blogManager1.getPostBody(p.getMessage().getId()));
|
||||||
|
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
}
|
}
|
||||||
@@ -217,10 +212,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
defaultInit();
|
defaultInit();
|
||||||
|
|
||||||
// add a post to blog1
|
// add a post to blog1
|
||||||
final String body = TestUtils.getRandomString(42);
|
final byte[] body = TestUtils.getRandomBytes(42);
|
||||||
BlogPost p = blogPostFactory
|
BlogPost p = blogPostFactory
|
||||||
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
|
.createBlogPost(blog1.getId(), null, clock.currentTimeMillis(),
|
||||||
author0, body);
|
null, author0, CONTENT_TYPE, body);
|
||||||
blogManager0.addLocalPost(p);
|
blogManager0.addLocalPost(p);
|
||||||
|
|
||||||
// check that post is now in blog1
|
// check that post is now in blog1
|
||||||
@@ -241,264 +236,26 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCanNotRemoveContactsPersonalBlog() throws Exception {
|
public void testAddAndRemoveBlog() throws Exception {
|
||||||
startLifecycles();
|
startLifecycles();
|
||||||
defaultInit();
|
defaultInit();
|
||||||
|
|
||||||
assertFalse(blogManager0.canBeRemoved(blog1.getId()));
|
String name = "Test Blog";
|
||||||
assertFalse(blogManager1.canBeRemoved(blog0.getId()));
|
String desc = "Description";
|
||||||
|
|
||||||
// the following two calls should throw a DbException now
|
// add blog
|
||||||
thrown.expect(DbException.class);
|
Blog blog = blogManager0.addBlog(author0, name, desc);
|
||||||
|
Collection<Blog> blogs0 = blogManager0.getBlogs();
|
||||||
|
assertEquals(3, blogs0.size());
|
||||||
|
assertTrue(blogs0.contains(blog));
|
||||||
|
assertEquals(2, blogManager0.getBlogs(author0).size());
|
||||||
|
|
||||||
blogManager0.removeBlog(blog1);
|
// remove blog
|
||||||
blogManager1.removeBlog(blog0);
|
blogManager0.removeBlog(blog);
|
||||||
|
blogs0 = blogManager0.getBlogs();
|
||||||
// blogs have not been removed
|
assertEquals(2, blogs0.size());
|
||||||
assertEquals(2, blogManager0.getBlogs().size());
|
assertFalse(blogs0.contains(blog));
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
assertEquals(1, blogManager0.getBlogs(author0).size());
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlogComment() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// add a post to blog0
|
|
||||||
final String body = TestUtils.getRandomString(42);
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
|
||||||
author0, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// sync the post over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// make sure post arrived
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
assertEquals(POST, headers1.iterator().next().getType());
|
|
||||||
|
|
||||||
// 1 adds a comment to that blog post
|
|
||||||
String comment = "This is a comment on a blog post!";
|
|
||||||
blogManager1
|
|
||||||
.addLocalComment(author1, blog1.getId(), comment,
|
|
||||||
headers1.iterator().next());
|
|
||||||
|
|
||||||
// sync comment over
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 2);
|
|
||||||
|
|
||||||
// make sure comment and wrapped post arrived
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(1, headers0.size());
|
|
||||||
assertEquals(COMMENT, headers0.iterator().next().getType());
|
|
||||||
BlogCommentHeader h = (BlogCommentHeader) headers0.iterator().next();
|
|
||||||
assertEquals(author0, h.getParent().getAuthor());
|
|
||||||
|
|
||||||
// ensure that body can be retrieved from wrapped post
|
|
||||||
assertEquals(body, blogManager0.getPostBody(h.getParentId()));
|
|
||||||
|
|
||||||
// 1 has only their own comment in their blog
|
|
||||||
headers1 = blogManager1.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlogCommentOnOwnPost() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// add a post to blog0
|
|
||||||
final String body = TestUtils.getRandomString(42);
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
|
||||||
author0, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// get header of own post
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers0.size());
|
|
||||||
BlogPostHeader header = headers0.iterator().next();
|
|
||||||
|
|
||||||
// add a comment on own post
|
|
||||||
String comment = "This is a comment on my own blog post!";
|
|
||||||
blogManager0
|
|
||||||
.addLocalComment(author0, blog0.getId(), comment, header);
|
|
||||||
|
|
||||||
// sync the post and comment over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 2);
|
|
||||||
|
|
||||||
// make sure post arrived
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(2, headers1.size());
|
|
||||||
for (BlogPostHeader h : headers1) {
|
|
||||||
if (h.getType() == POST) {
|
|
||||||
assertEquals(body, blogManager1.getPostBody(h.getId()));
|
|
||||||
} else {
|
|
||||||
assertEquals(comment, ((BlogCommentHeader)h).getComment());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCommentOnComment() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// add a post to blog0
|
|
||||||
final String body = TestUtils.getRandomString(42);
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
|
||||||
author0, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// sync the post over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// make sure post arrived
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
assertEquals(POST, headers1.iterator().next().getType());
|
|
||||||
|
|
||||||
// 1 reblogs that blog post
|
|
||||||
blogManager1
|
|
||||||
.addLocalComment(author1, blog1.getId(), null,
|
|
||||||
headers1.iterator().next());
|
|
||||||
|
|
||||||
// sync comment over
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 2);
|
|
||||||
|
|
||||||
// make sure comment and wrapped post arrived
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(1, headers0.size());
|
|
||||||
|
|
||||||
// get header of comment
|
|
||||||
BlogPostHeader cHeader = headers0.iterator().next();
|
|
||||||
assertEquals(COMMENT, cHeader.getType());
|
|
||||||
|
|
||||||
// comment on the comment
|
|
||||||
String comment = "This is a comment on a reblogged post.";
|
|
||||||
blogManager0
|
|
||||||
.addLocalComment(author0, blog0.getId(), comment, cHeader);
|
|
||||||
|
|
||||||
// sync comment over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 3);
|
|
||||||
|
|
||||||
// check that comment arrived
|
|
||||||
headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(2, headers1.size());
|
|
||||||
|
|
||||||
// get header of comment
|
|
||||||
cHeader = null;
|
|
||||||
for (BlogPostHeader h : headers1) {
|
|
||||||
if (h.getType() == COMMENT) {
|
|
||||||
cHeader = h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertTrue(cHeader != null);
|
|
||||||
|
|
||||||
// another comment on the comment
|
|
||||||
String comment2 = "This is a comment on a comment.";
|
|
||||||
blogManager1.addLocalComment(author1, blog1.getId(), comment2, cHeader);
|
|
||||||
|
|
||||||
// sync comment over
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 4);
|
|
||||||
|
|
||||||
// make sure new comment arrived
|
|
||||||
headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(2, headers0.size());
|
|
||||||
boolean satisfied = false;
|
|
||||||
for (BlogPostHeader h : headers0) {
|
|
||||||
assertEquals(COMMENT, h.getType());
|
|
||||||
BlogCommentHeader c = (BlogCommentHeader) h;
|
|
||||||
if (c.getComment() != null && c.getComment().equals(comment2)) {
|
|
||||||
assertEquals(author0, c.getParent().getAuthor());
|
|
||||||
assertEquals(WRAPPED_COMMENT, c.getParent().getType());
|
|
||||||
assertEquals(comment,
|
|
||||||
((BlogCommentHeader) c.getParent()).getComment());
|
|
||||||
assertEquals(WRAPPED_COMMENT,
|
|
||||||
((BlogCommentHeader) c.getParent()).getParent()
|
|
||||||
.getType());
|
|
||||||
assertEquals(WRAPPED_POST,
|
|
||||||
((BlogCommentHeader) ((BlogCommentHeader) c
|
|
||||||
.getParent()).getParent()).getParent()
|
|
||||||
.getType());
|
|
||||||
satisfied = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertTrue(satisfied);
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCommentOnOwnComment() throws Exception {
|
|
||||||
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// add a post to blog0
|
|
||||||
final String body = TestUtils.getRandomString(42);
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
|
||||||
author0, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// sync the post over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// make sure post arrived
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
assertEquals(POST, headers1.iterator().next().getType());
|
|
||||||
|
|
||||||
// 1 reblogs that blog post with a comment
|
|
||||||
String comment = "This is a comment on a post.";
|
|
||||||
blogManager1
|
|
||||||
.addLocalComment(author1, blog1.getId(), comment,
|
|
||||||
headers1.iterator().next());
|
|
||||||
|
|
||||||
// get comment from own blog
|
|
||||||
headers1 = blogManager1.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
assertEquals(COMMENT, headers1.iterator().next().getType());
|
|
||||||
BlogCommentHeader ch = (BlogCommentHeader) headers1.iterator().next();
|
|
||||||
assertEquals(comment, ch.getComment());
|
|
||||||
|
|
||||||
comment = "This is a comment on a post with a comment.";
|
|
||||||
blogManager1.addLocalComment(author1, blog1.getId(), comment, ch);
|
|
||||||
|
|
||||||
// sync both comments over (2 comments + 1 wrapped post)
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 3);
|
|
||||||
|
|
||||||
// make sure both comments arrived
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(2, headers0.size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
}
|
}
|
||||||
@@ -509,14 +266,14 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class Listener implements EventListener {
|
private class Listener implements EventListener {
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageStateChangedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||||
if (!event.isLocal()) {
|
if (!event.isLocal()) {
|
||||||
if (event.getState() == DELIVERED) {
|
if (event.getState() == DELIVERED) {
|
||||||
deliveryWaiter.resume();
|
deliveryWaiter.resume();
|
||||||
} else if (event.getState() == INVALID ||
|
} else if (event.getState() == VALID ||
|
||||||
|
event.getState() == INVALID ||
|
||||||
event.getState() == PENDING) {
|
event.getState() == PENDING) {
|
||||||
validationWaiter.resume();
|
validationWaiter.resume();
|
||||||
}
|
}
|
||||||
@@ -526,28 +283,39 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void defaultInit() throws DbException {
|
private void defaultInit() throws DbException {
|
||||||
getDefaultIdentities();
|
addDefaultIdentities();
|
||||||
addDefaultContacts();
|
addDefaultContacts();
|
||||||
listenToEvents();
|
listenToEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDefaultIdentities() throws DbException {
|
private void addDefaultIdentities() throws DbException {
|
||||||
author0 = identityManager0.getLocalAuthor();
|
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
|
||||||
author1 = identityManager1.getLocalAuthor();
|
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
|
||||||
blog0 = blogFactory.createBlog(author0);
|
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
|
||||||
blog1 = blogFactory.createBlog(author1);
|
author0 = authorFactory
|
||||||
|
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
|
||||||
|
identityManager0.addLocalAuthor(author0);
|
||||||
|
blog0 = blogFactory.createPersonalBlog(author0);
|
||||||
|
|
||||||
|
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
|
||||||
|
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
|
||||||
|
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
|
||||||
|
author1 = authorFactory
|
||||||
|
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
|
||||||
|
identityManager1.addLocalAuthor(author1);
|
||||||
|
blog1 = blogFactory.createPersonalBlog(author1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
private void addDefaultContacts() throws DbException {
|
||||||
// sharer adds invitee as contact
|
// sharer adds invitee as contact
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// invitee adds sharer back
|
// invitee adds sharer back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,8 +360,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
|
|||||||
// Start the lifecycle manager and wait for it to finish
|
// Start the lifecycle manager and wait for it to finish
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
lifecycleManager0 = t0.getLifecycleManager();
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
lifecycleManager1 = t1.getLifecycleManager();
|
||||||
lifecycleManager0.startServices(AUTHOR1);
|
lifecycleManager0.startServices();
|
||||||
lifecycleManager1.startServices(AUTHOR2);
|
lifecycleManager1.startServices();
|
||||||
lifecycleManager0.waitForStartup();
|
lifecycleManager0.waitForStartup();
|
||||||
lifecycleManager1.waitForStartup();
|
lifecycleManager1.waitForStartup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,743 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.Blog;
|
|
||||||
import org.briarproject.api.blogs.BlogInvitationRequest;
|
|
||||||
import org.briarproject.api.blogs.BlogInvitationResponse;
|
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
|
||||||
import org.briarproject.api.blogs.BlogPostFactory;
|
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.event.BlogInvitationReceivedEvent;
|
|
||||||
import org.briarproject.api.event.BlogInvitationResponseReceivedEvent;
|
|
||||||
import org.briarproject.api.event.Event;
|
|
||||||
import org.briarproject.api.event.EventListener;
|
|
||||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.api.sharing.InvitationMessage;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
import org.briarproject.api.sync.SyncSession;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
import org.briarproject.api.sync.ValidationManager.State;
|
|
||||||
import org.briarproject.api.system.Clock;
|
|
||||||
import org.briarproject.blogs.BlogsModule;
|
|
||||||
import org.briarproject.contact.ContactModule;
|
|
||||||
import org.briarproject.crypto.CryptoModule;
|
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
|
||||||
import org.briarproject.sharing.SharingModule;
|
|
||||||
import org.briarproject.sync.SyncModule;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
|
||||||
import static org.briarproject.api.blogs.BlogSharingManager.CLIENT_ID;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class BlogSharingIntegrationTest extends BriarIntegrationTest {
|
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1,
|
|
||||||
lifecycleManager2;
|
|
||||||
private SyncSessionFactory sync0, sync1;
|
|
||||||
private BlogManager blogManager0, blogManager1;
|
|
||||||
private MessageTracker messageTracker0, messageTracker1;
|
|
||||||
private ContactManager contactManager0, contactManager1, contactManager2;
|
|
||||||
private Contact contact1, contact2, contact01, contact02;
|
|
||||||
private ContactId contactId1, contactId01;
|
|
||||||
private IdentityManager identityManager0, identityManager1,
|
|
||||||
identityManager2;
|
|
||||||
private LocalAuthor author0, author1, author2;
|
|
||||||
private Blog blog0, blog1, blog2;
|
|
||||||
private SharerListener listener0;
|
|
||||||
private InviteeListener listener1;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Clock clock;
|
|
||||||
@Inject
|
|
||||||
AuthorFactory authorFactory;
|
|
||||||
@Inject
|
|
||||||
ContactGroupFactory contactGroupFactory;
|
|
||||||
@Inject
|
|
||||||
BlogPostFactory blogPostFactory;
|
|
||||||
@Inject
|
|
||||||
CryptoComponent cryptoComponent;
|
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
|
||||||
private volatile BlogSharingManager blogSharingManager0;
|
|
||||||
private volatile BlogSharingManager blogSharingManager1;
|
|
||||||
private volatile BlogSharingManager blogSharingManager2;
|
|
||||||
private volatile Waiter eventWaiter;
|
|
||||||
private volatile Waiter msgWaiter;
|
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
|
||||||
private final SecretKey master = TestUtils.getSecretKey();
|
|
||||||
private final int TIMEOUT = 15000;
|
|
||||||
private final String SHARER = "Sharer";
|
|
||||||
private final String INVITEE = "Invitee";
|
|
||||||
private final String CONTACT2 = "Contact2";
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(BlogSharingIntegrationTest.class.getName());
|
|
||||||
|
|
||||||
private BlogSharingIntegrationTestComponent t0, t1, t2;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() {
|
|
||||||
BlogSharingIntegrationTestComponent component =
|
|
||||||
DaggerBlogSharingIntegrationTestComponent.builder().build();
|
|
||||||
component.inject(this);
|
|
||||||
injectEagerSingletons(component);
|
|
||||||
|
|
||||||
assertTrue(testDir.mkdirs());
|
|
||||||
File t0Dir = new File(testDir, SHARER);
|
|
||||||
t0 = DaggerBlogSharingIntegrationTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
|
|
||||||
injectEagerSingletons(t0);
|
|
||||||
File t1Dir = new File(testDir, INVITEE);
|
|
||||||
t1 = DaggerBlogSharingIntegrationTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
|
|
||||||
injectEagerSingletons(t1);
|
|
||||||
File t2Dir = new File(testDir, CONTACT2);
|
|
||||||
t2 = DaggerBlogSharingIntegrationTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t2Dir)).build();
|
|
||||||
injectEagerSingletons(t2);
|
|
||||||
|
|
||||||
identityManager0 = t0.getIdentityManager();
|
|
||||||
identityManager1 = t1.getIdentityManager();
|
|
||||||
identityManager2 = t2.getIdentityManager();
|
|
||||||
contactManager0 = t0.getContactManager();
|
|
||||||
contactManager1 = t1.getContactManager();
|
|
||||||
contactManager2 = t2.getContactManager();
|
|
||||||
blogManager0 = t0.getBlogManager();
|
|
||||||
blogManager1 = t1.getBlogManager();
|
|
||||||
messageTracker0 = t0.getMessageTracker();
|
|
||||||
messageTracker1 = t1.getMessageTracker();
|
|
||||||
blogSharingManager0 = t0.getBlogSharingManager();
|
|
||||||
blogSharingManager1 = t1.getBlogSharingManager();
|
|
||||||
blogSharingManager2 = t2.getBlogSharingManager();
|
|
||||||
sync0 = t0.getSyncSessionFactory();
|
|
||||||
sync1 = t1.getSyncSessionFactory();
|
|
||||||
|
|
||||||
// initialize waiters fresh for each test
|
|
||||||
eventWaiter = new Waiter();
|
|
||||||
msgWaiter = new Waiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
assertFalse(blogSharingManager0.canBeShared(blog1.getId(), contact1));
|
|
||||||
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact2));
|
|
||||||
assertFalse(blogSharingManager1.canBeShared(blog0.getId(), contact01));
|
|
||||||
assertFalse(blogSharingManager2.canBeShared(blog0.getId(), contact02));
|
|
||||||
|
|
||||||
// create invitation
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog1.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// sync invitation
|
|
||||||
sync0To1();
|
|
||||||
// make sure the invitee ignored the request for their own blog
|
|
||||||
assertFalse(listener1.requestReceived);
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccessfulSharing() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// invitee has own blog and that of the sharer
|
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// get sharing group and assert group message count
|
|
||||||
GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID, contact1)
|
|
||||||
.getId();
|
|
||||||
assertGroupCount(messageTracker0, g, 1, 0);
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
assertGroupCount(messageTracker1, g, 2, 1);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
assertGroupCount(messageTracker0, g, 2, 1);
|
|
||||||
|
|
||||||
// blog was added successfully
|
|
||||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// invitee has one invitation message from sharer
|
|
||||||
List<InvitationMessage> list =
|
|
||||||
new ArrayList<>(blogSharingManager1
|
|
||||||
.getInvitationMessages(contactId01));
|
|
||||||
assertEquals(2, list.size());
|
|
||||||
// check other things are alright with the message
|
|
||||||
for (InvitationMessage m : list) {
|
|
||||||
if (m instanceof BlogInvitationRequest) {
|
|
||||||
BlogInvitationRequest invitation =
|
|
||||||
(BlogInvitationRequest) m;
|
|
||||||
assertFalse(invitation.isAvailable());
|
|
||||||
assertEquals(blog2.getAuthor().getName(),
|
|
||||||
invitation.getBlogAuthorName());
|
|
||||||
assertEquals(contactId1, invitation.getContactId());
|
|
||||||
assertEquals("Hi!", invitation.getMessage());
|
|
||||||
} else {
|
|
||||||
BlogInvitationResponse response =
|
|
||||||
(BlogInvitationResponse) m;
|
|
||||||
assertEquals(contactId01, response.getContactId());
|
|
||||||
assertTrue(response.wasAccepted());
|
|
||||||
assertTrue(response.isLocal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sharer has own invitation message and response
|
|
||||||
assertEquals(2,
|
|
||||||
blogSharingManager0.getInvitationMessages(contactId1)
|
|
||||||
.size());
|
|
||||||
// blog can not be shared again
|
|
||||||
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
|
||||||
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
|
|
||||||
|
|
||||||
// group message count is still correct
|
|
||||||
assertGroupCount(messageTracker0, g, 2, 1);
|
|
||||||
assertGroupCount(messageTracker1, g, 2, 1);
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDeclinedSharing() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee deny all requests
|
|
||||||
defaultInit(false);
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, null);
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// blog was not added
|
|
||||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
|
||||||
// blog is no longer available to invitee who declined
|
|
||||||
assertEquals(0, blogSharingManager1.getInvitations().size());
|
|
||||||
|
|
||||||
// invitee has one invitation message from sharer and one response
|
|
||||||
List<InvitationMessage> list =
|
|
||||||
new ArrayList<>(blogSharingManager1
|
|
||||||
.getInvitationMessages(contactId01));
|
|
||||||
assertEquals(2, list.size());
|
|
||||||
// check things are alright with the message
|
|
||||||
for (InvitationMessage m : list) {
|
|
||||||
if (m instanceof BlogInvitationRequest) {
|
|
||||||
BlogInvitationRequest invitation =
|
|
||||||
(BlogInvitationRequest) m;
|
|
||||||
assertFalse(invitation.isAvailable());
|
|
||||||
assertEquals(blog2.getAuthor().getName(),
|
|
||||||
invitation.getBlogAuthorName());
|
|
||||||
assertEquals(contactId1, invitation.getContactId());
|
|
||||||
assertEquals(null, invitation.getMessage());
|
|
||||||
} else {
|
|
||||||
BlogInvitationResponse response =
|
|
||||||
(BlogInvitationResponse) m;
|
|
||||||
assertEquals(contactId01, response.getContactId());
|
|
||||||
assertFalse(response.wasAccepted());
|
|
||||||
assertTrue(response.isLocal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sharer has own invitation message and response
|
|
||||||
assertEquals(2,
|
|
||||||
blogSharingManager0.getInvitationMessages(contactId1)
|
|
||||||
.size());
|
|
||||||
// blog can be shared again
|
|
||||||
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInviteeLeavesAfterFinished() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// blog was added successfully
|
|
||||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
assertTrue(blogManager1.getBlogs().contains(blog2));
|
|
||||||
|
|
||||||
// sharer shares blog with invitee
|
|
||||||
assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
|
|
||||||
.contains(contact1));
|
|
||||||
// invitee gets blog shared by sharer
|
|
||||||
assertTrue(blogSharingManager1.getSharedBy(blog2.getId())
|
|
||||||
.contains(contact01));
|
|
||||||
|
|
||||||
// invitee un-subscribes from blog
|
|
||||||
blogManager1.removeBlog(blog2);
|
|
||||||
|
|
||||||
// send leave message to sharer
|
|
||||||
sync1To0();
|
|
||||||
|
|
||||||
// blog is gone
|
|
||||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// sharer no longer shares blog with invitee
|
|
||||||
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
|
|
||||||
.contains(contact1));
|
|
||||||
// invitee no longer gets blog shared by sharer
|
|
||||||
assertFalse(blogSharingManager1.getSharedBy(blog2.getId())
|
|
||||||
.contains(contact01));
|
|
||||||
// blog can be shared again
|
|
||||||
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
|
||||||
assertTrue(blogSharingManager1.canBeShared(blog2.getId(), contact01));
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testInvitationForExistingBlog() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
// 1 and 2 are adding each other
|
|
||||||
contactManager1.addContact(author2,
|
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contactManager2.addContact(author1,
|
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// sharer sends invitation for 2's blog to 1
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// make sure blog2 is shared by 0
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
blogSharingManager1.getSharedBy(blog2.getId());
|
|
||||||
assertEquals(1, contacts.size());
|
|
||||||
assertTrue(contacts.contains(contact01));
|
|
||||||
|
|
||||||
// make sure 1 knows that they have blog2 already
|
|
||||||
Collection<InvitationMessage> messages =
|
|
||||||
blogSharingManager1.getInvitationMessages(contactId01);
|
|
||||||
assertEquals(2, messages.size());
|
|
||||||
assertEquals(blog2, blogManager1.getBlog(blog2.getId()));
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// blog was not added, because it was there already
|
|
||||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRemovingSharedBlog() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// blog was added successfully and is shared both ways
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
Collection<Contact> sharedWith =
|
|
||||||
blogSharingManager0.getSharedWith(blog2.getId());
|
|
||||||
assertEquals(1, sharedWith.size());
|
|
||||||
assertEquals(contact1, sharedWith.iterator().next());
|
|
||||||
Collection<Contact> sharedBy =
|
|
||||||
blogSharingManager1.getSharedBy(blog2.getId());
|
|
||||||
assertEquals(1, sharedBy.size());
|
|
||||||
assertEquals(contact01, sharedBy.iterator().next());
|
|
||||||
|
|
||||||
// shared blog can be removed
|
|
||||||
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
|
|
||||||
|
|
||||||
// invitee removes blog again
|
|
||||||
blogManager1.removeBlog(blog2);
|
|
||||||
|
|
||||||
// sync LEAVE message
|
|
||||||
sync1To0();
|
|
||||||
|
|
||||||
// sharer does not share this blog anymore with invitee
|
|
||||||
sharedWith =
|
|
||||||
blogSharingManager0.getSharedWith(blog2.getId());
|
|
||||||
assertEquals(0, sharedWith.size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSharedBlogBecomesPermanent() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
// initialize and let invitee accept all requests
|
|
||||||
defaultInit(true);
|
|
||||||
|
|
||||||
// invitee only sees two blogs
|
|
||||||
assertEquals(2, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// sharer sends invitation for 2's blog to 1
|
|
||||||
blogSharingManager0
|
|
||||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
|
||||||
|
|
||||||
// sync first request message
|
|
||||||
sync0To1();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// make sure blog2 is shared by 0
|
|
||||||
Collection<Contact> contacts =
|
|
||||||
blogSharingManager1.getSharedBy(blog2.getId());
|
|
||||||
assertEquals(1, contacts.size());
|
|
||||||
assertTrue(contacts.contains(contact01));
|
|
||||||
|
|
||||||
// sync response back
|
|
||||||
sync1To0();
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener0.responseReceived);
|
|
||||||
|
|
||||||
// blog was added and can be removed
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
|
|
||||||
|
|
||||||
// 1 and 2 are adding each other
|
|
||||||
contactManager1.addContact(author2,
|
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contactManager2.addContact(author1,
|
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
assertEquals(3, blogManager1.getBlogs().size());
|
|
||||||
|
|
||||||
// now blog can not be removed anymore
|
|
||||||
assertFalse(blogManager1.canBeRemoved(blog2.getId()));
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws InterruptedException {
|
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SharerListener implements EventListener {
|
|
||||||
|
|
||||||
private volatile boolean responseReceived = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
|
||||||
State s = event.getState();
|
|
||||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
|
||||||
LOG.info("TEST: Sharer received message");
|
|
||||||
msgWaiter.resume();
|
|
||||||
}
|
|
||||||
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
|
||||||
BlogInvitationResponseReceivedEvent event =
|
|
||||||
(BlogInvitationResponseReceivedEvent) e;
|
|
||||||
eventWaiter.assertEquals(contactId1, event.getContactId());
|
|
||||||
responseReceived = true;
|
|
||||||
eventWaiter.resume();
|
|
||||||
}
|
|
||||||
// this is only needed for tests where a blog is re-shared
|
|
||||||
else if (e instanceof BlogInvitationReceivedEvent) {
|
|
||||||
BlogInvitationReceivedEvent event =
|
|
||||||
(BlogInvitationReceivedEvent) e;
|
|
||||||
eventWaiter.assertEquals(contactId1, event.getContactId());
|
|
||||||
Blog b = event.getShareable();
|
|
||||||
try {
|
|
||||||
Contact c = contactManager0.getContact(contactId1);
|
|
||||||
blogSharingManager0.respondToInvitation(b, c, true);
|
|
||||||
} catch (DbException ex) {
|
|
||||||
eventWaiter.rethrow(ex);
|
|
||||||
} finally {
|
|
||||||
eventWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class InviteeListener implements EventListener {
|
|
||||||
|
|
||||||
private volatile boolean requestReceived = false;
|
|
||||||
|
|
||||||
private final boolean accept, answer;
|
|
||||||
|
|
||||||
private InviteeListener(boolean accept, boolean answer) {
|
|
||||||
this.accept = accept;
|
|
||||||
this.answer = answer;
|
|
||||||
}
|
|
||||||
|
|
||||||
private InviteeListener(boolean accept) {
|
|
||||||
this(accept, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
|
||||||
State s = event.getState();
|
|
||||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
|
||||||
LOG.info("TEST: Invitee received message");
|
|
||||||
msgWaiter.resume();
|
|
||||||
}
|
|
||||||
} else if (e instanceof BlogInvitationReceivedEvent) {
|
|
||||||
BlogInvitationReceivedEvent event =
|
|
||||||
(BlogInvitationReceivedEvent) e;
|
|
||||||
requestReceived = true;
|
|
||||||
if (!answer) return;
|
|
||||||
Blog b = event.getShareable();
|
|
||||||
try {
|
|
||||||
eventWaiter.assertEquals(1,
|
|
||||||
blogSharingManager1.getInvitations().size());
|
|
||||||
Contact c =
|
|
||||||
contactManager1.getContact(event.getContactId());
|
|
||||||
blogSharingManager1.respondToInvitation(b, c, accept);
|
|
||||||
} catch (DbException ex) {
|
|
||||||
eventWaiter.rethrow(ex);
|
|
||||||
} finally {
|
|
||||||
eventWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this is only needed for tests where a blog is re-shared
|
|
||||||
else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
|
||||||
BlogInvitationResponseReceivedEvent event =
|
|
||||||
(BlogInvitationResponseReceivedEvent) e;
|
|
||||||
eventWaiter.assertEquals(contactId01, event.getContactId());
|
|
||||||
eventWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startLifecycles() throws InterruptedException {
|
|
||||||
// Start the lifecycle manager and wait for it to finish
|
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
|
||||||
lifecycleManager2 = t2.getLifecycleManager();
|
|
||||||
lifecycleManager0.startServices(SHARER);
|
|
||||||
lifecycleManager1.startServices(INVITEE);
|
|
||||||
lifecycleManager2.startServices(CONTACT2);
|
|
||||||
lifecycleManager0.waitForStartup();
|
|
||||||
lifecycleManager1.waitForStartup();
|
|
||||||
lifecycleManager2.waitForStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopLifecycles() throws InterruptedException {
|
|
||||||
// Clean up
|
|
||||||
lifecycleManager0.stopServices();
|
|
||||||
lifecycleManager1.stopServices();
|
|
||||||
lifecycleManager2.stopServices();
|
|
||||||
lifecycleManager0.waitForShutdown();
|
|
||||||
lifecycleManager1.waitForShutdown();
|
|
||||||
lifecycleManager2.waitForShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defaultInit(boolean accept) throws DbException {
|
|
||||||
getDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
getPersonalBlogOfSharer();
|
|
||||||
listenToEvents(accept);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getDefaultIdentities() throws DbException {
|
|
||||||
author0 = identityManager0.getLocalAuthor();
|
|
||||||
author1 = identityManager1.getLocalAuthor();
|
|
||||||
author2 = identityManager2.getLocalAuthor();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
|
||||||
// sharer adds invitee as contact
|
|
||||||
contactId1 = contactManager0.addContact(author1,
|
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contact1 = contactManager0.getContact(contactId1);
|
|
||||||
// sharer adds second contact
|
|
||||||
ContactId contactId2 = contactManager0.addContact(author2,
|
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contact2 = contactManager0.getContact(contactId2);
|
|
||||||
// contacts add sharer back
|
|
||||||
contactId01 = contactManager1.addContact(author0,
|
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contact01 = contactManager1.getContact(contactId01);
|
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
contact02 = contactManager2.getContact(contactId02);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getPersonalBlogOfSharer() throws DbException {
|
|
||||||
blog0 = blogManager0.getPersonalBlog(author0);
|
|
||||||
blog1 = blogManager0.getPersonalBlog(author1);
|
|
||||||
blog2 = blogManager0.getPersonalBlog(author2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listenToEvents(boolean accept) {
|
|
||||||
listener0 = new SharerListener();
|
|
||||||
t0.getEventBus().addListener(listener0);
|
|
||||||
listener1 = new InviteeListener(accept);
|
|
||||||
t1.getEventBus().addListener(listener1);
|
|
||||||
SharerListener listener2 = new SharerListener();
|
|
||||||
t2.getEventBus().addListener(listener2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync0To1() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync0, contactId01, sync1, contactId1,
|
|
||||||
"Sharer to Invitee");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync1To0() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync1, contactId1, sync0, contactId01,
|
|
||||||
"Invitee to Sharer");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
|
||||||
SyncSessionFactory toSync, ContactId toId, String debug)
|
|
||||||
throws IOException, TimeoutException {
|
|
||||||
|
|
||||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
// Create an outgoing sync session
|
|
||||||
SyncSession sessionFrom =
|
|
||||||
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
|
||||||
// Write whatever needs to be written
|
|
||||||
sessionFrom.run();
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
|
||||||
// Create an incoming sync session
|
|
||||||
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
|
|
||||||
// Read whatever needs to be read
|
|
||||||
sessionTo.run();
|
|
||||||
in.close();
|
|
||||||
|
|
||||||
// wait for message to actually arrive
|
|
||||||
msgWaiter.await(TIMEOUT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectEagerSingletons(
|
|
||||||
BlogSharingIntegrationTestComponent component) {
|
|
||||||
|
|
||||||
component.inject(new LifecycleModule.EagerSingletons());
|
|
||||||
component.inject(new BlogsModule.EagerSingletons());
|
|
||||||
component.inject(new CryptoModule.EagerSingletons());
|
|
||||||
component.inject(new ContactModule.EagerSingletons());
|
|
||||||
component.inject(new TransportModule.EagerSingletons());
|
|
||||||
component.inject(new SharingModule.EagerSingletons());
|
|
||||||
component.inject(new SyncModule.EagerSingletons());
|
|
||||||
component.inject(new PropertiesModule.EagerSingletons());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
|
||||||
import org.briarproject.api.blogs.BlogSharingManager;
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.event.EventBus;
|
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
import org.briarproject.blogs.BlogsModule;
|
|
||||||
import org.briarproject.clients.ClientsModule;
|
|
||||||
import org.briarproject.contact.ContactModule;
|
|
||||||
import org.briarproject.crypto.CryptoModule;
|
|
||||||
import org.briarproject.data.DataModule;
|
|
||||||
import org.briarproject.db.DatabaseModule;
|
|
||||||
import org.briarproject.event.EventModule;
|
|
||||||
import org.briarproject.forum.ForumModule;
|
|
||||||
import org.briarproject.identity.IdentityModule;
|
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
|
||||||
import org.briarproject.messaging.MessagingModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
|
||||||
import org.briarproject.sharing.SharingModule;
|
|
||||||
import org.briarproject.sync.SyncModule;
|
|
||||||
import org.briarproject.system.SystemModule;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import dagger.Component;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Component(modules = {
|
|
||||||
TestDatabaseModule.class,
|
|
||||||
TestPluginsModule.class,
|
|
||||||
TestSeedProviderModule.class,
|
|
||||||
ClientsModule.class,
|
|
||||||
ContactModule.class,
|
|
||||||
CryptoModule.class,
|
|
||||||
DataModule.class,
|
|
||||||
DatabaseModule.class,
|
|
||||||
EventModule.class,
|
|
||||||
BlogsModule.class,
|
|
||||||
ForumModule.class,
|
|
||||||
IdentityModule.class,
|
|
||||||
LifecycleModule.class,
|
|
||||||
PropertiesModule.class,
|
|
||||||
SharingModule.class,
|
|
||||||
SyncModule.class,
|
|
||||||
SystemModule.class,
|
|
||||||
TransportModule.class,
|
|
||||||
MessagingModule.class
|
|
||||||
})
|
|
||||||
interface BlogSharingIntegrationTestComponent {
|
|
||||||
|
|
||||||
void inject(BlogSharingIntegrationTest testCase);
|
|
||||||
|
|
||||||
void inject(ContactModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(CryptoModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(BlogsModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(LifecycleModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(PropertiesModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(SharingModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(SyncModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(TransportModule.EagerSingletons init);
|
|
||||||
|
|
||||||
LifecycleManager getLifecycleManager();
|
|
||||||
|
|
||||||
EventBus getEventBus();
|
|
||||||
|
|
||||||
IdentityManager getIdentityManager();
|
|
||||||
|
|
||||||
ContactManager getContactManager();
|
|
||||||
|
|
||||||
BlogSharingManager getBlogSharingManager();
|
|
||||||
|
|
||||||
BlogManager getBlogManager();
|
|
||||||
|
|
||||||
MessageTracker getMessageTracker();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
public abstract class BriarIntegrationTest extends BriarTestCase {
|
|
||||||
|
|
||||||
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
|
|
||||||
long msgCount, long unreadCount, long latestMsg)
|
|
||||||
throws DbException {
|
|
||||||
|
|
||||||
GroupCount groupCount = tracker.getGroupCount(g);
|
|
||||||
assertEquals(msgCount, groupCount.getMsgCount());
|
|
||||||
assertEquals(unreadCount, groupCount.getUnreadCount());
|
|
||||||
assertEquals(latestMsg, groupCount.getLatestMsgTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
|
|
||||||
long msgCount, long unreadCount) throws DbException {
|
|
||||||
|
|
||||||
GroupCount c1 = tracker.getGroupCount(g);
|
|
||||||
assertEquals(msgCount, c1.getMsgCount());
|
|
||||||
assertEquals(unreadCount, c1.getUnreadCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -4,11 +4,9 @@ import junit.framework.Assert;
|
|||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
@@ -36,7 +34,7 @@ import org.briarproject.properties.PropertiesModule;
|
|||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
import org.briarproject.transport.TransportModule;
|
import org.briarproject.transport.TransportModule;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.briarproject.util.StringUtils;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -55,18 +53,19 @@ import static junit.framework.Assert.assertEquals;
|
|||||||
import static junit.framework.Assert.assertNull;
|
import static junit.framework.Assert.assertNull;
|
||||||
import static junit.framework.TestCase.assertFalse;
|
import static junit.framework.TestCase.assertFalse;
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
||||||
|
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
||||||
|
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class ForumManagerTest extends BriarIntegrationTest {
|
public class ForumManagerTest {
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
||||||
private SyncSessionFactory sync0, sync1;
|
private SyncSessionFactory sync0, sync1;
|
||||||
private ForumManager forumManager0, forumManager1;
|
private ForumManager forumManager0, forumManager1;
|
||||||
private ContactManager contactManager0, contactManager1;
|
private ContactManager contactManager0, contactManager1;
|
||||||
private MessageTracker messageTracker0, messageTracker1;
|
|
||||||
private ContactId contactId0,contactId1;
|
private ContactId contactId0,contactId1;
|
||||||
private IdentityManager identityManager0, identityManager1;
|
private IdentityManager identityManager0, identityManager1;
|
||||||
private LocalAuthor author0, author1;
|
private LocalAuthor author0, author1;
|
||||||
@@ -77,8 +76,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
@Inject
|
@Inject
|
||||||
AuthorFactory authorFactory;
|
AuthorFactory authorFactory;
|
||||||
@Inject
|
@Inject
|
||||||
CryptoComponent crypto;
|
|
||||||
@Inject
|
|
||||||
ForumPostFactory forumPostFactory;
|
ForumPostFactory forumPostFactory;
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
// objects accessed from background threads need to be volatile
|
||||||
@@ -119,8 +116,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
identityManager1 = t1.getIdentityManager();
|
identityManager1 = t1.getIdentityManager();
|
||||||
contactManager0 = t0.getContactManager();
|
contactManager0 = t0.getContactManager();
|
||||||
contactManager1 = t1.getContactManager();
|
contactManager1 = t1.getContactManager();
|
||||||
messageTracker0 = t0.getMessageTracker();
|
|
||||||
messageTracker1 = t1.getMessageTracker();
|
|
||||||
forumManager0 = t0.getForumManager();
|
forumManager0 = t0.getForumManager();
|
||||||
forumManager1 = t1.getForumManager();
|
forumManager1 = t1.getForumManager();
|
||||||
forumSharingManager0 = t0.getForumSharingManager();
|
forumSharingManager0 = t0.getForumSharingManager();
|
||||||
@@ -133,17 +128,16 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
deliveryWaiter = new Waiter();
|
deliveryWaiter = new Waiter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ForumPost createForumPost(GroupId groupId,
|
private ForumPost createForumPost(GroupId groupId, ForumPost parent,
|
||||||
@Nullable ForumPost parent, String body, long ms) throws Exception {
|
String body, long ms) throws Exception {
|
||||||
return forumPostFactory.createPost(groupId, ms,
|
return forumPostFactory.createAnonymousPost(groupId, ms,
|
||||||
parent == null ? null : parent.getMessage().getId(),
|
parent == null ? null : parent.getMessage().getId(),
|
||||||
author0, body);
|
"text/plain", StringUtils.toUtf8(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForumPost() throws Exception {
|
public void testForumPost() throws Exception {
|
||||||
startLifecycles();
|
startLifecycles();
|
||||||
getDefaultIdentities();
|
|
||||||
Forum forum = forumManager0.addForum("TestForum");
|
Forum forum = forumManager0.addForum("TestForum");
|
||||||
assertEquals(1, forumManager0.getForums().size());
|
assertEquals(1, forumManager0.getForums().size());
|
||||||
final long ms1 = clock.currentTimeMillis() - 1000L;
|
final long ms1 = clock.currentTimeMillis() - 1000L;
|
||||||
@@ -157,24 +151,15 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
|
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
|
||||||
assertEquals(ms2, post2.getMessage().getTimestamp());
|
assertEquals(ms2, post2.getMessage().getTimestamp());
|
||||||
forumManager0.addLocalPost(post1);
|
forumManager0.addLocalPost(post1);
|
||||||
forumManager0.setReadFlag(forum.getGroup().getId(),
|
forumManager0.setReadFlag(post1.getMessage().getId(), true);
|
||||||
post1.getMessage().getId(), true);
|
|
||||||
assertGroupCount(messageTracker0, forum.getGroup().getId(), 1, 0,
|
|
||||||
post1.getMessage().getTimestamp());
|
|
||||||
forumManager0.addLocalPost(post2);
|
forumManager0.addLocalPost(post2);
|
||||||
forumManager0.setReadFlag(forum.getGroup().getId(),
|
forumManager0.setReadFlag(post2.getMessage().getId(), false);
|
||||||
post2.getMessage().getId(), false);
|
|
||||||
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
|
|
||||||
post2.getMessage().getTimestamp());
|
|
||||||
forumManager0.setReadFlag(forum.getGroup().getId(),
|
|
||||||
post2.getMessage().getId(), false);
|
|
||||||
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
|
|
||||||
post2.getMessage().getTimestamp());
|
|
||||||
Collection<ForumPostHeader> headers =
|
Collection<ForumPostHeader> headers =
|
||||||
forumManager0.getPostHeaders(forum.getGroup().getId());
|
forumManager0.getPostHeaders(forum.getGroup().getId());
|
||||||
assertEquals(2, headers.size());
|
assertEquals(2, headers.size());
|
||||||
for (ForumPostHeader h : headers) {
|
for (ForumPostHeader h : headers) {
|
||||||
final String hBody = forumManager0.getPostBody(h.getId());
|
final String hBody =
|
||||||
|
StringUtils.fromUtf8(forumManager0.getPostBody(h.getId()));
|
||||||
|
|
||||||
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
|
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
|
||||||
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
|
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
|
||||||
@@ -218,29 +203,23 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
forumManager0.addLocalPost(post1);
|
forumManager0.addLocalPost(post1);
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
||||||
assertGroupCount(messageTracker0, g, 1, 0, time);
|
|
||||||
assertGroupCount(messageTracker1, g, 0, 0, 0);
|
|
||||||
|
|
||||||
// send post to 1
|
// send post to 1
|
||||||
sync0To1();
|
sync0To1();
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
deliveryWaiter.await(TIMEOUT, 1);
|
||||||
assertEquals(1, forumManager1.getPostHeaders(g).size());
|
assertEquals(1, forumManager1.getPostHeaders(g).size());
|
||||||
assertGroupCount(messageTracker1, g, 1, 1, time);
|
|
||||||
|
|
||||||
// add another forum post
|
// add another forum post
|
||||||
long time2 = clock.currentTimeMillis();
|
time = clock.currentTimeMillis();
|
||||||
ForumPost post2 = createForumPost(g, null, "b", time2);
|
ForumPost post2 = createForumPost(g, null, "b", time);
|
||||||
forumManager1.addLocalPost(post2);
|
forumManager1.addLocalPost(post2);
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||||
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
||||||
assertGroupCount(messageTracker0, g, 1, 0, time);
|
|
||||||
assertGroupCount(messageTracker1, g, 2, 1, time2);
|
|
||||||
|
|
||||||
// send post to 0
|
// send post to 0
|
||||||
sync1To0();
|
sync1To0();
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
deliveryWaiter.await(TIMEOUT, 1);
|
||||||
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
||||||
assertGroupCount(messageTracker0, g, 2, 1, time2);
|
|
||||||
|
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
}
|
}
|
||||||
@@ -319,7 +298,7 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
||||||
|
|
||||||
// send the child post to 1
|
// send posts to 1
|
||||||
sync0To1();
|
sync0To1();
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
validationWaiter.await(TIMEOUT, 1);
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||||
@@ -348,14 +327,14 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class Listener implements EventListener {
|
private class Listener implements EventListener {
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageStateChangedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||||
if (!event.isLocal()) {
|
if (!event.isLocal()) {
|
||||||
if (event.getState() == DELIVERED) {
|
if (event.getState() == DELIVERED) {
|
||||||
deliveryWaiter.resume();
|
deliveryWaiter.resume();
|
||||||
} else if (event.getState() == INVALID ||
|
} else if (event.getState() == VALID ||
|
||||||
|
event.getState() == INVALID ||
|
||||||
event.getState() == PENDING) {
|
event.getState() == PENDING) {
|
||||||
validationWaiter.resume();
|
validationWaiter.resume();
|
||||||
}
|
}
|
||||||
@@ -365,27 +344,33 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void defaultInit() throws DbException {
|
private void defaultInit() throws DbException {
|
||||||
getDefaultIdentities();
|
addDefaultIdentities();
|
||||||
addDefaultContacts();
|
addDefaultContacts();
|
||||||
addForum();
|
addForum();
|
||||||
listenToEvents();
|
listenToEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDefaultIdentities() throws DbException {
|
private void addDefaultIdentities() throws DbException {
|
||||||
author0 = identityManager0.getLocalAuthor();
|
author0 = authorFactory.createLocalAuthor(SHARER,
|
||||||
author1 = identityManager1.getLocalAuthor();
|
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||||
|
TestUtils.getRandomBytes(123));
|
||||||
|
identityManager0.addLocalAuthor(author0);
|
||||||
|
author1 = authorFactory.createLocalAuthor(INVITEE,
|
||||||
|
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||||
|
TestUtils.getRandomBytes(123));
|
||||||
|
identityManager1.addLocalAuthor(author1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
private void addDefaultContacts() throws DbException {
|
||||||
// sharer adds invitee as contact
|
// sharer adds invitee as contact
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// invitee adds sharer back
|
// invitee adds sharer back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,8 +419,8 @@ public class ForumManagerTest extends BriarIntegrationTest {
|
|||||||
// Start the lifecycle manager and wait for it to finish
|
// Start the lifecycle manager and wait for it to finish
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
lifecycleManager0 = t0.getLifecycleManager();
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
lifecycleManager1 = t1.getLifecycleManager();
|
||||||
lifecycleManager0.startServices(SHARER);
|
lifecycleManager0.startServices();
|
||||||
lifecycleManager1.startServices(INVITEE);
|
lifecycleManager1.startServices();
|
||||||
lifecycleManager0.waitForStartup();
|
lifecycleManager0.waitForStartup();
|
||||||
lifecycleManager1.waitForStartup();
|
lifecycleManager1.waitForStartup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.api.forum.ForumManager;
|
import org.briarproject.api.forum.ForumManager;
|
||||||
@@ -8,7 +7,6 @@ import org.briarproject.api.forum.ForumSharingManager;
|
|||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
import org.briarproject.api.sync.SyncSessionFactory;
|
||||||
import org.briarproject.blogs.BlogsModule;
|
|
||||||
import org.briarproject.clients.ClientsModule;
|
import org.briarproject.clients.ClientsModule;
|
||||||
import org.briarproject.contact.ContactModule;
|
import org.briarproject.contact.ContactModule;
|
||||||
import org.briarproject.crypto.CryptoModule;
|
import org.briarproject.crypto.CryptoModule;
|
||||||
@@ -18,7 +16,6 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -41,17 +38,15 @@ import dagger.Component;
|
|||||||
DatabaseModule.class,
|
DatabaseModule.class,
|
||||||
EventModule.class,
|
EventModule.class,
|
||||||
ForumModule.class,
|
ForumModule.class,
|
||||||
BlogsModule.class,
|
|
||||||
IdentityModule.class,
|
IdentityModule.class,
|
||||||
LifecycleModule.class,
|
LifecycleModule.class,
|
||||||
PropertiesModule.class,
|
PropertiesModule.class,
|
||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class,
|
TransportModule.class
|
||||||
MessagingModule.class
|
|
||||||
})
|
})
|
||||||
interface ForumManagerTestComponent {
|
public interface ForumManagerTestComponent {
|
||||||
|
|
||||||
void inject(ForumManagerTest testCase);
|
void inject(ForumManagerTest testCase);
|
||||||
|
|
||||||
@@ -79,8 +74,6 @@ interface ForumManagerTestComponent {
|
|||||||
|
|
||||||
ContactManager getContactManager();
|
ContactManager getContactManager();
|
||||||
|
|
||||||
MessageTracker getMessageTracker();
|
|
||||||
|
|
||||||
ForumSharingManager getForumSharingManager();
|
ForumSharingManager getForumSharingManager();
|
||||||
|
|
||||||
ForumManager getForumManager();
|
ForumManager getForumManager();
|
||||||
|
|||||||
@@ -3,13 +3,16 @@ package org.briarproject;
|
|||||||
import net.jodah.concurrentunit.Waiter;
|
import net.jodah.concurrentunit.Waiter;
|
||||||
|
|
||||||
import org.briarproject.api.Bytes;
|
import org.briarproject.api.Bytes;
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
|
||||||
import org.briarproject.api.clients.MessageQueueManager;
|
import org.briarproject.api.clients.MessageQueueManager;
|
||||||
|
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||||
import org.briarproject.api.clients.SessionId;
|
import org.briarproject.api.clients.SessionId;
|
||||||
import org.briarproject.api.contact.Contact;
|
import org.briarproject.api.contact.Contact;
|
||||||
import org.briarproject.api.contact.ContactId;
|
import org.briarproject.api.contact.ContactId;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
import org.briarproject.api.crypto.CryptoComponent;
|
||||||
|
import org.briarproject.api.crypto.KeyPair;
|
||||||
|
import org.briarproject.api.crypto.KeyParser;
|
||||||
|
import org.briarproject.api.crypto.PrivateKey;
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.data.BdfList;
|
import org.briarproject.api.data.BdfList;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
@@ -22,8 +25,7 @@ import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
|||||||
import org.briarproject.api.event.ForumInvitationResponseReceivedEvent;
|
import org.briarproject.api.event.ForumInvitationResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
import org.briarproject.api.event.MessageStateChangedEvent;
|
||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
import org.briarproject.api.forum.ForumInvitationMessage;
|
||||||
import org.briarproject.api.forum.ForumInvitationResponse;
|
|
||||||
import org.briarproject.api.forum.ForumManager;
|
import org.briarproject.api.forum.ForumManager;
|
||||||
import org.briarproject.api.forum.ForumPost;
|
import org.briarproject.api.forum.ForumPost;
|
||||||
import org.briarproject.api.forum.ForumPostFactory;
|
import org.briarproject.api.forum.ForumPostFactory;
|
||||||
@@ -33,8 +35,7 @@ import org.briarproject.api.identity.AuthorFactory;
|
|||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sharing.SharingInvitationItem;
|
import org.briarproject.api.sync.ClientId;
|
||||||
import org.briarproject.api.sharing.InvitationMessage;
|
|
||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
import org.briarproject.api.sync.SyncSession;
|
import org.briarproject.api.sync.SyncSession;
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
import org.briarproject.api.sync.SyncSessionFactory;
|
||||||
@@ -68,7 +69,6 @@ import javax.inject.Inject;
|
|||||||
|
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
||||||
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
|
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
|
||||||
import static org.briarproject.api.forum.ForumSharingManager.CLIENT_ID;
|
|
||||||
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||||
@@ -111,7 +111,6 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
private final String SHARER = "Sharer";
|
private final String SHARER = "Sharer";
|
||||||
private final String INVITEE = "Invitee";
|
private final String INVITEE = "Invitee";
|
||||||
private final String SHARER2 = "Sharer2";
|
private final String SHARER2 = "Sharer2";
|
||||||
private boolean respond = true;
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
|
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
|
||||||
@@ -184,33 +183,22 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
// forum was added successfully
|
// forum was added successfully
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
|
|
||||||
// invitee has one invitation message from sharer
|
// invitee has one invitation message from sharer
|
||||||
List<InvitationMessage> list =
|
List<ForumInvitationMessage> list =
|
||||||
new ArrayList<>(forumSharingManager1
|
new ArrayList<>(forumSharingManager1
|
||||||
.getInvitationMessages(contactId0));
|
.getInvitationMessages(contactId0));
|
||||||
assertEquals(2, list.size());
|
assertEquals(1, list.size());
|
||||||
// check other things are alright with the forum message
|
// check other things are alright with the forum message
|
||||||
for (InvitationMessage m : list) {
|
ForumInvitationMessage invitation = list.get(0);
|
||||||
if (m instanceof ForumInvitationRequest) {
|
assertFalse(invitation.isAvailable());
|
||||||
ForumInvitationRequest invitation =
|
assertEquals(forum0.getName(), invitation.getForumName());
|
||||||
(ForumInvitationRequest) m;
|
assertEquals(contactId1, invitation.getContactId());
|
||||||
assertFalse(invitation.isAvailable());
|
assertEquals("Hi!", invitation.getMessage());
|
||||||
assertEquals(forum0.getName(), invitation.getForumName());
|
// sharer has own invitation message
|
||||||
assertEquals(contactId1, invitation.getContactId());
|
assertEquals(1,
|
||||||
assertEquals("Hi!", invitation.getMessage());
|
|
||||||
} else {
|
|
||||||
ForumInvitationResponse response =
|
|
||||||
(ForumInvitationResponse) m;
|
|
||||||
assertEquals(contactId0, response.getContactId());
|
|
||||||
assertTrue(response.wasAccepted());
|
|
||||||
assertTrue(response.isLocal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sharer has own invitation message and response
|
|
||||||
assertEquals(2,
|
|
||||||
forumSharingManager0.getInvitationMessages(contactId1)
|
forumSharingManager0.getInvitationMessages(contactId1)
|
||||||
.size());
|
.size());
|
||||||
// forum can not be shared again
|
// forum can not be shared again
|
||||||
@@ -245,35 +233,24 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
// forum was not added
|
// forum was not added
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||||
assertEquals(0, forumManager1.getForums().size());
|
assertEquals(0, forumManager1.getForums().size());
|
||||||
// forum is no longer available to invitee who declined
|
// forum is no longer available to invitee who declined
|
||||||
assertEquals(0, forumSharingManager1.getInvitations().size());
|
assertEquals(0, forumSharingManager1.getInvited().size());
|
||||||
|
|
||||||
// invitee has one invitation message from sharer and one response
|
// invitee has one invitation message from sharer
|
||||||
List<InvitationMessage> list =
|
List<ForumInvitationMessage> list =
|
||||||
new ArrayList<>(forumSharingManager1
|
new ArrayList<>(forumSharingManager1
|
||||||
.getInvitationMessages(contactId0));
|
.getInvitationMessages(contactId0));
|
||||||
assertEquals(2, list.size());
|
assertEquals(1, list.size());
|
||||||
// check things are alright with the forum message
|
// check other things are alright with the forum message
|
||||||
for (InvitationMessage m : list) {
|
ForumInvitationMessage invitation = list.get(0);
|
||||||
if (m instanceof ForumInvitationRequest) {
|
assertFalse(invitation.isAvailable());
|
||||||
ForumInvitationRequest invitation =
|
assertEquals(forum0.getName(), invitation.getForumName());
|
||||||
(ForumInvitationRequest) m;
|
assertEquals(contactId1, invitation.getContactId());
|
||||||
assertFalse(invitation.isAvailable());
|
assertEquals(null, invitation.getMessage());
|
||||||
assertEquals(forum0.getName(), invitation.getForumName());
|
// sharer has own invitation message
|
||||||
assertEquals(contactId1, invitation.getContactId());
|
assertEquals(1,
|
||||||
assertEquals(null, invitation.getMessage());
|
|
||||||
} else {
|
|
||||||
ForumInvitationResponse response =
|
|
||||||
(ForumInvitationResponse) m;
|
|
||||||
assertEquals(contactId0, response.getContactId());
|
|
||||||
assertFalse(response.wasAccepted());
|
|
||||||
assertTrue(response.isLocal());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sharer has own invitation message and response
|
|
||||||
assertEquals(2,
|
|
||||||
forumSharingManager0.getInvitationMessages(contactId1)
|
forumSharingManager0.getInvitationMessages(contactId1)
|
||||||
.size());
|
.size());
|
||||||
// forum can be shared again
|
// forum can be shared again
|
||||||
@@ -306,7 +283,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
// forum was added successfully
|
// forum was added successfully
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
assertTrue(forumManager1.getForums().contains(forum0));
|
assertTrue(forumManager1.getForums().contains(forum0));
|
||||||
|
|
||||||
@@ -326,7 +303,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
syncToSharer();
|
syncToSharer();
|
||||||
|
|
||||||
// forum is gone
|
// forum is gone
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||||
assertEquals(0, forumManager1.getForums().size());
|
assertEquals(0, forumManager1.getForums().size());
|
||||||
|
|
||||||
// sharer no longer shares forum with invitee
|
// sharer no longer shares forum with invitee
|
||||||
@@ -366,7 +343,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
// forum was added successfully
|
// forum was added successfully
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
assertTrue(forumManager1.getForums().contains(forum0));
|
assertTrue(forumManager1.getForums().contains(forum0));
|
||||||
|
|
||||||
@@ -407,7 +384,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
public void testSharerLeavesBeforeResponse() throws Exception {
|
public void testSharerLeavesBeforeResponse() throws Exception {
|
||||||
startLifecycles();
|
startLifecycles();
|
||||||
try {
|
try {
|
||||||
// initialize except event listeners
|
// initialize and let invitee accept all requests
|
||||||
defaultInit(true);
|
defaultInit(true);
|
||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
@@ -417,39 +394,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
// sharer un-subscribes from forum
|
// sharer un-subscribes from forum
|
||||||
forumManager0.removeForum(forum0);
|
forumManager0.removeForum(forum0);
|
||||||
|
|
||||||
// prevent invitee response before syncing messages
|
// from here on expect the response to fail with an AssertionError,
|
||||||
respond = false;
|
// because there is in fact no invited forum available anymore
|
||||||
|
thrown.expect(AssertionError.class);
|
||||||
|
|
||||||
// sync first request message and leave message
|
// sync first request message and leave message
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, 2,
|
syncToInvitee();
|
||||||
"Sharer to Invitee");
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener1.requestReceived);
|
assertTrue(listener1.requestReceived);
|
||||||
|
|
||||||
// ensure that invitee has no forum invitations available
|
// invitee has no forums available
|
||||||
assertEquals(0, forumSharingManager1.getInvitations().size());
|
assertEquals(0, forumSharingManager1.getInvited().size());
|
||||||
assertEquals(0, forumManager1.getForums().size());
|
|
||||||
|
|
||||||
// Try again, this time allow the response
|
|
||||||
addForumForSharer();
|
|
||||||
respond = true;
|
|
||||||
|
|
||||||
// send invitation
|
|
||||||
forumSharingManager0
|
|
||||||
.sendInvitation(forum0.getId(), contactId1, null);
|
|
||||||
|
|
||||||
// sharer un-subscribes from forum
|
|
||||||
forumManager0.removeForum(forum0);
|
|
||||||
|
|
||||||
// sync first request message and leave message
|
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, 2,
|
|
||||||
"Sharer to Invitee");
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// ensure that invitee has no forum invitations available
|
|
||||||
assertEquals(0, forumSharingManager1.getInvitations().size());
|
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
|
||||||
} finally {
|
} finally {
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
}
|
}
|
||||||
@@ -483,20 +438,20 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
listener1.requestReceived = false;
|
listener1.requestReceived = false;
|
||||||
|
|
||||||
// get SessionId from invitation
|
// get SessionId from invitation
|
||||||
List<InvitationMessage> list = new ArrayList<>(
|
List<ForumInvitationMessage> list = new ArrayList<>(
|
||||||
forumSharingManager1
|
forumSharingManager1
|
||||||
.getInvitationMessages(contactId0));
|
.getInvitationMessages(contactId0));
|
||||||
assertEquals(2, list.size());
|
assertEquals(1, list.size());
|
||||||
InvitationMessage msg = list.get(0);
|
ForumInvitationMessage msg = list.get(0);
|
||||||
SessionId sessionId = msg.getSessionId();
|
SessionId sessionId = msg.getSessionId();
|
||||||
assertEquals(sessionId, list.get(1).getSessionId());
|
|
||||||
|
|
||||||
// get all sorts of stuff needed to send a message
|
// get all sorts of stuff needed to send a message
|
||||||
DatabaseComponent db = t0.getDatabaseComponent();
|
DatabaseComponent db = t0.getDatabaseComponent();
|
||||||
MessageQueueManager queue = t0.getMessageQueueManager();
|
MessageQueueManager queue = t0.getMessageQueueManager();
|
||||||
Contact c1 = contactManager0.getContact(contactId1);
|
Contact c1 = contactManager0.getContact(contactId1);
|
||||||
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
|
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
|
||||||
Group group = groupFactory.createContactGroup(CLIENT_ID, c1);
|
Group group = groupFactory
|
||||||
|
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
|
||||||
long time = clock.currentTimeMillis();
|
long time = clock.currentTimeMillis();
|
||||||
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
|
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
|
||||||
sessionId.getBytes(),
|
sessionId.getBytes(),
|
||||||
@@ -509,7 +464,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
queue.sendMessage(txn, group, time, body, new Metadata());
|
queue.sendMessage(txn, group, time, body, new Metadata());
|
||||||
db.commitTransaction(txn);
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
@@ -546,9 +501,6 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// forum was added successfully
|
// forum was added successfully
|
||||||
assertEquals(1, forumManager1.getForums().size());
|
assertEquals(1, forumManager1.getForums().size());
|
||||||
assertEquals(2,
|
|
||||||
forumSharingManager0.getInvitationMessages(contactId1)
|
|
||||||
.size());
|
|
||||||
|
|
||||||
// invitee now shares same forum back
|
// invitee now shares same forum back
|
||||||
forumSharingManager1.sendInvitation(forum0.getId(),
|
forumSharingManager1.sendInvitation(forum0.getId(),
|
||||||
@@ -560,10 +512,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// make sure that no new request was received
|
// make sure that no new request was received
|
||||||
assertFalse(listener0.requestReceived);
|
assertFalse(listener0.requestReceived);
|
||||||
assertEquals(2,
|
assertEquals(1,
|
||||||
forumSharingManager0.getInvitationMessages(contactId1)
|
forumSharingManager0.getInvitationMessages(contactId1)
|
||||||
.size());
|
.size());
|
||||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
|
||||||
} finally {
|
} finally {
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
}
|
}
|
||||||
@@ -580,7 +531,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
DatabaseComponent db1 = t1.getDatabaseComponent();
|
DatabaseComponent db1 = t1.getDatabaseComponent();
|
||||||
Transaction txn = db1.startTransaction(false);
|
Transaction txn = db1.startTransaction(false);
|
||||||
db1.addGroup(txn, forum0.getGroup());
|
db1.addGroup(txn, forum0.getGroup());
|
||||||
db1.commitTransaction(txn);
|
txn.setComplete();
|
||||||
db1.endTransaction(txn);
|
db1.endTransaction(txn);
|
||||||
|
|
||||||
// send invitation
|
// send invitation
|
||||||
@@ -615,9 +566,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener0.responseReceived);
|
assertTrue(listener0.responseReceived);
|
||||||
|
|
||||||
assertEquals(2, forumSharingManager0
|
assertEquals(1, forumSharingManager0
|
||||||
.getInvitationMessages(contactId1).size());
|
.getInvitationMessages(contactId1).size());
|
||||||
assertEquals(3, forumSharingManager1
|
assertEquals(2, forumSharingManager1
|
||||||
.getInvitationMessages(contactId0).size());
|
.getInvitationMessages(contactId0).size());
|
||||||
} else {
|
} else {
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
@@ -628,9 +579,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener1.responseReceived);
|
assertTrue(listener1.responseReceived);
|
||||||
|
|
||||||
assertEquals(3, forumSharingManager0
|
assertEquals(2, forumSharingManager0
|
||||||
.getInvitationMessages(contactId1).size());
|
.getInvitationMessages(contactId1).size());
|
||||||
assertEquals(2, forumSharingManager1
|
assertEquals(1, forumSharingManager1
|
||||||
.getInvitationMessages(contactId0).size());
|
.getInvitationMessages(contactId0).size());
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -665,13 +616,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
||||||
|
|
||||||
// remember SessionId from invitation
|
// remember SessionId from invitation
|
||||||
List<InvitationMessage> list = new ArrayList<>(
|
List<ForumInvitationMessage> list = new ArrayList<>(
|
||||||
forumSharingManager1
|
forumSharingManager1
|
||||||
.getInvitationMessages(contactId0));
|
.getInvitationMessages(contactId0));
|
||||||
assertEquals(2, list.size());
|
assertEquals(1, list.size());
|
||||||
InvitationMessage msg = list.get(0);
|
ForumInvitationMessage msg = list.get(0);
|
||||||
SessionId sessionId = msg.getSessionId();
|
SessionId sessionId = msg.getSessionId();
|
||||||
assertEquals(sessionId, list.get(1).getSessionId());
|
|
||||||
|
|
||||||
// contacts now remove each other
|
// contacts now remove each other
|
||||||
contactManager0.removeContact(contactId1);
|
contactManager0.removeContact(contactId1);
|
||||||
@@ -690,8 +640,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
DatabaseComponent db = t0.getDatabaseComponent();
|
DatabaseComponent db = t0.getDatabaseComponent();
|
||||||
MessageQueueManager queue = t0.getMessageQueueManager();
|
MessageQueueManager queue = t0.getMessageQueueManager();
|
||||||
Contact c1 = contactManager0.getContact(contactId1);
|
Contact c1 = contactManager0.getContact(contactId1);
|
||||||
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
|
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
|
||||||
Group group = groupFactory.createContactGroup(CLIENT_ID, c1);
|
Group group = groupFactory
|
||||||
|
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
|
||||||
long time = clock.currentTimeMillis();
|
long time = clock.currentTimeMillis();
|
||||||
|
|
||||||
// construct a new message re-using the old SessionId
|
// construct a new message re-using the old SessionId
|
||||||
@@ -706,7 +657,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
Transaction txn = db.startTransaction(false);
|
Transaction txn = db.startTransaction(false);
|
||||||
try {
|
try {
|
||||||
queue.sendMessage(txn, group, time, body, new Metadata());
|
queue.sendMessage(txn, group, time, body, new Metadata());
|
||||||
db.commitTransaction(txn);
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
}
|
}
|
||||||
@@ -727,7 +678,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
startLifecycles();
|
startLifecycles();
|
||||||
try {
|
try {
|
||||||
// initialize
|
// initialize
|
||||||
getDefaultIdentities();
|
addDefaultIdentities();
|
||||||
addDefaultContacts();
|
addDefaultContacts();
|
||||||
addForumForSharer();
|
addForumForSharer();
|
||||||
|
|
||||||
@@ -735,7 +686,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
DatabaseComponent db2 = t2.getDatabaseComponent();
|
DatabaseComponent db2 = t2.getDatabaseComponent();
|
||||||
Transaction txn = db2.startTransaction(false);
|
Transaction txn = db2.startTransaction(false);
|
||||||
db2.addGroup(txn, forum0.getGroup());
|
db2.addGroup(txn, forum0.getGroup());
|
||||||
db2.commitTransaction(txn);
|
txn.setComplete();
|
||||||
db2.endTransaction(txn);
|
db2.endTransaction(txn);
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
@@ -756,15 +707,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
forumSharingManager2
|
forumSharingManager2
|
||||||
.sendInvitation(forum0.getId(), contactId1, null);
|
.sendInvitation(forum0.getId(), contactId1, null);
|
||||||
// sync second request message
|
// sync second request message
|
||||||
deliverMessage(sync2, contactId2, sync1, contactId1, 1,
|
deliverMessage(sync2, contactId2, sync1, contactId1,
|
||||||
"Sharer2 to Invitee");
|
"Sharer2 to Invitee");
|
||||||
|
|
||||||
// make sure we now have two invitations to the same forum available
|
// make sure we now have two invitations to the same forum available
|
||||||
Collection<SharingInvitationItem> forums =
|
Collection<Forum> forums = forumSharingManager1.getInvited();
|
||||||
forumSharingManager1.getInvitations();
|
|
||||||
assertEquals(1, forums.size());
|
assertEquals(1, forums.size());
|
||||||
assertEquals(2, forums.iterator().next().getNewSharers().size());
|
|
||||||
assertEquals(forum0, forums.iterator().next().getShareable());
|
|
||||||
assertEquals(2,
|
assertEquals(2,
|
||||||
forumSharingManager1.getSharedBy(forum0.getId()).size());
|
forumSharingManager1.getSharedBy(forum0.getId()).size());
|
||||||
|
|
||||||
@@ -777,7 +725,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
Contact c2 = contactManager1.getContact(contactId2);
|
Contact c2 = contactManager1.getContact(contactId2);
|
||||||
forumSharingManager1.respondToInvitation(forum0, c2, true);
|
forumSharingManager1.respondToInvitation(forum0, c2, true);
|
||||||
// sync response
|
// sync response
|
||||||
deliverMessage(sync1, contactId21, sync2, contactId2, 1,
|
deliverMessage(sync1, contactId21, sync2, contactId2,
|
||||||
"Invitee to Sharer2");
|
"Invitee to Sharer2");
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
eventWaiter.await(TIMEOUT, 1);
|
||||||
assertTrue(listener2.responseReceived);
|
assertTrue(listener2.responseReceived);
|
||||||
@@ -816,10 +764,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// sharer posts into the forum
|
// sharer posts into the forum
|
||||||
long time = clock.currentTimeMillis();
|
long time = clock.currentTimeMillis();
|
||||||
String body = TestUtils.getRandomString(42);
|
byte[] body = TestUtils.getRandomBytes(42);
|
||||||
|
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
|
||||||
|
PrivateKey key = keyParser.parsePrivateKey(author0.getPrivateKey());
|
||||||
ForumPost p = forumPostFactory
|
ForumPost p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author0,
|
.createPseudonymousPost(forum0.getId(), time, null, author0,
|
||||||
body);
|
"text/plain", body, key);
|
||||||
forumManager0.addLocalPost(p);
|
forumManager0.addLocalPost(p);
|
||||||
|
|
||||||
// sync forum post
|
// sync forum post
|
||||||
@@ -835,10 +785,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// now invitee creates a post
|
// now invitee creates a post
|
||||||
time = clock.currentTimeMillis();
|
time = clock.currentTimeMillis();
|
||||||
body = TestUtils.getRandomString(42);
|
body = TestUtils.getRandomBytes(42);
|
||||||
|
key = keyParser.parsePrivateKey(author1.getPrivateKey());
|
||||||
p = forumPostFactory
|
p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author1,
|
.createPseudonymousPost(forum0.getId(), time, null, author1,
|
||||||
body);
|
"text/plain", body, key);
|
||||||
forumManager1.addLocalPost(p);
|
forumManager1.addLocalPost(p);
|
||||||
|
|
||||||
// sync forum post
|
// sync forum post
|
||||||
@@ -879,10 +830,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// now invitee creates a post
|
// now invitee creates a post
|
||||||
time = clock.currentTimeMillis();
|
time = clock.currentTimeMillis();
|
||||||
body = TestUtils.getRandomString(42);
|
body = TestUtils.getRandomBytes(42);
|
||||||
|
key = keyParser.parsePrivateKey(author1.getPrivateKey());
|
||||||
p = forumPostFactory
|
p = forumPostFactory
|
||||||
.createPost(forum0.getId(), time, null, author1,
|
.createPseudonymousPost(forum0.getId(), time, null, author1,
|
||||||
body);
|
"text/plain", body, key);
|
||||||
forumManager1.addLocalPost(p);
|
forumManager1.addLocalPost(p);
|
||||||
|
|
||||||
// sync forum post
|
// sync forum post
|
||||||
@@ -912,16 +864,23 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
private class SharerListener implements EventListener {
|
private class SharerListener implements EventListener {
|
||||||
|
|
||||||
private volatile boolean requestReceived = false;
|
volatile boolean requestReceived = false;
|
||||||
private volatile boolean responseReceived = false;
|
volatile boolean responseReceived = false;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageStateChangedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||||
State s = event.getState();
|
State s = event.getState();
|
||||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
ClientId c = event.getClientId();
|
||||||
LOG.info("TEST: Sharer received message");
|
if ((s == DELIVERED || s == INVALID) &&
|
||||||
|
c.equals(forumSharingManager0.getClientId()) &&
|
||||||
|
!event.isLocal()) {
|
||||||
|
LOG.info("TEST: Sharer received message in group " +
|
||||||
|
event.getMessage().getGroupId().hashCode());
|
||||||
|
msgWaiter.resume();
|
||||||
|
} else if (s == DELIVERED && !event.isLocal() &&
|
||||||
|
c.equals(forumManager0.getClientId())) {
|
||||||
|
LOG.info("TEST: Sharer received forum post");
|
||||||
msgWaiter.resume();
|
msgWaiter.resume();
|
||||||
}
|
}
|
||||||
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
|
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
|
||||||
@@ -937,7 +896,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
(ForumInvitationReceivedEvent) e;
|
(ForumInvitationReceivedEvent) e;
|
||||||
eventWaiter.assertEquals(contactId1, event.getContactId());
|
eventWaiter.assertEquals(contactId1, event.getContactId());
|
||||||
requestReceived = true;
|
requestReceived = true;
|
||||||
Forum f = event.getShareable();
|
Forum f = event.getForum();
|
||||||
try {
|
try {
|
||||||
Contact c = contactManager0.getContact(contactId1);
|
Contact c = contactManager0.getContact(contactId1);
|
||||||
forumSharingManager0.respondToInvitation(f, c, true);
|
forumSharingManager0.respondToInvitation(f, c, true);
|
||||||
@@ -952,27 +911,34 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
private class InviteeListener implements EventListener {
|
private class InviteeListener implements EventListener {
|
||||||
|
|
||||||
private volatile boolean requestReceived = false;
|
volatile boolean requestReceived = false;
|
||||||
private volatile boolean responseReceived = false;
|
volatile boolean responseReceived = false;
|
||||||
|
|
||||||
private final boolean accept, answer;
|
private final boolean accept, answer;
|
||||||
|
|
||||||
private InviteeListener(boolean accept, boolean answer) {
|
InviteeListener(boolean accept, boolean answer) {
|
||||||
this.accept = accept;
|
this.accept = accept;
|
||||||
this.answer = answer;
|
this.answer = answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private InviteeListener(boolean accept) {
|
InviteeListener(boolean accept) {
|
||||||
this(accept, true);
|
this(accept, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageStateChangedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||||
State s = event.getState();
|
State s = event.getState();
|
||||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
ClientId c = event.getClientId();
|
||||||
LOG.info("TEST: Invitee received message");
|
if ((s == DELIVERED || s == INVALID) &&
|
||||||
|
c.equals(forumSharingManager0.getClientId()) &&
|
||||||
|
!event.isLocal()) {
|
||||||
|
LOG.info("TEST: Invitee received message in group " +
|
||||||
|
event.getMessage().getGroupId().hashCode());
|
||||||
|
msgWaiter.resume();
|
||||||
|
} else if (s == DELIVERED && !event.isLocal() &&
|
||||||
|
c.equals(forumManager0.getClientId())) {
|
||||||
|
LOG.info("TEST: Invitee received forum post");
|
||||||
msgWaiter.resume();
|
msgWaiter.resume();
|
||||||
}
|
}
|
||||||
} else if (e instanceof ForumInvitationReceivedEvent) {
|
} else if (e instanceof ForumInvitationReceivedEvent) {
|
||||||
@@ -980,19 +946,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
(ForumInvitationReceivedEvent) e;
|
(ForumInvitationReceivedEvent) e;
|
||||||
requestReceived = true;
|
requestReceived = true;
|
||||||
if (!answer) return;
|
if (!answer) return;
|
||||||
Forum f = event.getShareable();
|
Forum f = event.getForum();
|
||||||
try {
|
try {
|
||||||
eventWaiter.assertEquals(1,
|
eventWaiter.assertEquals(1,
|
||||||
forumSharingManager1.getInvitations().size());
|
forumSharingManager1.getInvited().size());
|
||||||
SharingInvitationItem invitation =
|
|
||||||
forumSharingManager1.getInvitations().iterator()
|
|
||||||
.next();
|
|
||||||
eventWaiter.assertEquals(f, invitation.getShareable());
|
|
||||||
if (respond) {
|
|
||||||
Contact c =
|
Contact c =
|
||||||
contactManager1.getContact(event.getContactId());
|
contactManager1.getContact(event.getContactId());
|
||||||
forumSharingManager1.respondToInvitation(f, c, accept);
|
forumSharingManager1.respondToInvitation(f, c, accept);
|
||||||
}
|
|
||||||
} catch (DbException ex) {
|
} catch (DbException ex) {
|
||||||
eventWaiter.rethrow(ex);
|
eventWaiter.rethrow(ex);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -1015,9 +975,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
lifecycleManager0 = t0.getLifecycleManager();
|
lifecycleManager0 = t0.getLifecycleManager();
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
lifecycleManager1 = t1.getLifecycleManager();
|
||||||
lifecycleManager2 = t2.getLifecycleManager();
|
lifecycleManager2 = t2.getLifecycleManager();
|
||||||
lifecycleManager0.startServices(SHARER);
|
lifecycleManager0.startServices();
|
||||||
lifecycleManager1.startServices(INVITEE);
|
lifecycleManager1.startServices();
|
||||||
lifecycleManager2.startServices(SHARER2);
|
lifecycleManager2.startServices();
|
||||||
lifecycleManager0.waitForStartup();
|
lifecycleManager0.waitForStartup();
|
||||||
lifecycleManager1.waitForStartup();
|
lifecycleManager1.waitForStartup();
|
||||||
lifecycleManager2.waitForStartup();
|
lifecycleManager2.waitForStartup();
|
||||||
@@ -1034,37 +994,51 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void defaultInit(boolean accept) throws DbException {
|
private void defaultInit(boolean accept) throws DbException {
|
||||||
getDefaultIdentities();
|
addDefaultIdentities();
|
||||||
addDefaultContacts();
|
addDefaultContacts();
|
||||||
addForumForSharer();
|
addForumForSharer();
|
||||||
listenToEvents(accept);
|
listenToEvents(accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getDefaultIdentities() throws DbException {
|
private void addDefaultIdentities() throws DbException {
|
||||||
author0 = identityManager0.getLocalAuthor();
|
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
|
||||||
author1 = identityManager1.getLocalAuthor();
|
author0 = authorFactory.createLocalAuthor(SHARER,
|
||||||
author2 = identityManager2.getLocalAuthor();
|
keyPair.getPublic().getEncoded(),
|
||||||
|
keyPair.getPrivate().getEncoded());
|
||||||
|
identityManager0.addLocalAuthor(author0);
|
||||||
|
|
||||||
|
keyPair = cryptoComponent.generateSignatureKeyPair();
|
||||||
|
author1 = authorFactory.createLocalAuthor(INVITEE,
|
||||||
|
keyPair.getPublic().getEncoded(),
|
||||||
|
keyPair.getPrivate().getEncoded());
|
||||||
|
identityManager1.addLocalAuthor(author1);
|
||||||
|
|
||||||
|
keyPair = cryptoComponent.generateSignatureKeyPair();
|
||||||
|
author2 = authorFactory.createLocalAuthor(SHARER2,
|
||||||
|
keyPair.getPublic().getEncoded(),
|
||||||
|
keyPair.getPrivate().getEncoded());
|
||||||
|
identityManager2.addLocalAuthor(author2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
private void addDefaultContacts() throws DbException {
|
||||||
// sharer adds invitee as contact
|
// sharer adds invitee as contact
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// second sharer does the same
|
// second sharer does the same
|
||||||
contactId21 = contactManager2.addContact(author1,
|
contactId21 = contactManager2.addContact(author1,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// invitee adds sharers back
|
// invitee adds sharers back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager1.addContact(author2,
|
contactId2 = contactManager1.addContact(author2,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1083,17 +1057,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void syncToInvitee() throws IOException, TimeoutException {
|
private void syncToInvitee() throws IOException, TimeoutException {
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, 1,
|
deliverMessage(sync0, contactId0, sync1, contactId1,
|
||||||
"Sharer to Invitee");
|
"Sharer to Invitee");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void syncToSharer() throws IOException, TimeoutException {
|
private void syncToSharer() throws IOException, TimeoutException {
|
||||||
deliverMessage(sync1, contactId1, sync0, contactId0, 1,
|
deliverMessage(sync1, contactId1, sync0, contactId0,
|
||||||
"Invitee to Sharer");
|
"Invitee to Sharer");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
||||||
SyncSessionFactory toSync, ContactId toId, int num, String debug)
|
SyncSessionFactory toSync, ContactId toId, String debug)
|
||||||
throws IOException, TimeoutException {
|
throws IOException, TimeoutException {
|
||||||
|
|
||||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
||||||
@@ -1114,7 +1088,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
|||||||
in.close();
|
in.close();
|
||||||
|
|
||||||
// wait for message to actually arrive
|
// wait for message to actually arrive
|
||||||
msgWaiter.await(TIMEOUT, num);
|
msgWaiter.await(TIMEOUT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectEagerSingletons(
|
private void injectEagerSingletons(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package org.briarproject;
|
|||||||
|
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
import org.briarproject.api.clients.ClientHelper;
|
||||||
import org.briarproject.api.clients.MessageQueueManager;
|
import org.briarproject.api.clients.MessageQueueManager;
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
import org.briarproject.api.clients.PrivateGroupFactory;
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
@@ -11,7 +11,6 @@ import org.briarproject.api.forum.ForumSharingManager;
|
|||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
import org.briarproject.api.sync.SyncSessionFactory;
|
||||||
import org.briarproject.blogs.BlogsModule;
|
|
||||||
import org.briarproject.clients.ClientsModule;
|
import org.briarproject.clients.ClientsModule;
|
||||||
import org.briarproject.contact.ContactModule;
|
import org.briarproject.contact.ContactModule;
|
||||||
import org.briarproject.crypto.CryptoModule;
|
import org.briarproject.crypto.CryptoModule;
|
||||||
@@ -21,7 +20,6 @@ import org.briarproject.event.EventModule;
|
|||||||
import org.briarproject.forum.ForumModule;
|
import org.briarproject.forum.ForumModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sharing.SharingModule;
|
import org.briarproject.sharing.SharingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -44,17 +42,15 @@ import dagger.Component;
|
|||||||
DatabaseModule.class,
|
DatabaseModule.class,
|
||||||
EventModule.class,
|
EventModule.class,
|
||||||
ForumModule.class,
|
ForumModule.class,
|
||||||
BlogsModule.class,
|
|
||||||
IdentityModule.class,
|
IdentityModule.class,
|
||||||
LifecycleModule.class,
|
LifecycleModule.class,
|
||||||
PropertiesModule.class,
|
PropertiesModule.class,
|
||||||
SharingModule.class,
|
SharingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
TransportModule.class,
|
TransportModule.class
|
||||||
MessagingModule.class
|
|
||||||
})
|
})
|
||||||
interface ForumSharingIntegrationTestComponent {
|
public interface ForumSharingIntegrationTestComponent {
|
||||||
|
|
||||||
void inject(ForumSharingIntegrationTest testCase);
|
void inject(ForumSharingIntegrationTest testCase);
|
||||||
|
|
||||||
@@ -92,7 +88,7 @@ interface ForumSharingIntegrationTestComponent {
|
|||||||
|
|
||||||
DatabaseComponent getDatabaseComponent();
|
DatabaseComponent getDatabaseComponent();
|
||||||
|
|
||||||
ContactGroupFactory getContactGroupFactory();
|
PrivateGroupFactory getPrivateGroupFactory();
|
||||||
|
|
||||||
ClientHelper getClientHelper();
|
ClientHelper getClientHelper();
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,5 @@
|
|||||||
package org.briarproject.introduction;
|
package org.briarproject;
|
||||||
|
|
||||||
import org.briarproject.TestDatabaseModule;
|
|
||||||
import org.briarproject.TestPluginsModule;
|
|
||||||
import org.briarproject.TestSeedProviderModule;
|
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
import org.briarproject.api.contact.ContactManager;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
@@ -20,8 +15,10 @@ import org.briarproject.data.DataModule;
|
|||||||
import org.briarproject.db.DatabaseModule;
|
import org.briarproject.db.DatabaseModule;
|
||||||
import org.briarproject.event.EventModule;
|
import org.briarproject.event.EventModule;
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
|
import org.briarproject.introduction.IntroductionGroupFactory;
|
||||||
|
import org.briarproject.introduction.IntroductionModule;
|
||||||
|
import org.briarproject.introduction.MessageSender;
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
import org.briarproject.lifecycle.LifecycleModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
import org.briarproject.properties.PropertiesModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
import org.briarproject.system.SystemModule;
|
import org.briarproject.system.SystemModule;
|
||||||
@@ -48,10 +45,9 @@ import dagger.Component;
|
|||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
SystemModule.class,
|
SystemModule.class,
|
||||||
DataModule.class,
|
DataModule.class,
|
||||||
PropertiesModule.class,
|
PropertiesModule.class
|
||||||
MessagingModule.class
|
|
||||||
})
|
})
|
||||||
interface IntroductionIntegrationTestComponent {
|
public interface IntroductionIntegrationTestComponent {
|
||||||
|
|
||||||
void inject(IntroductionIntegrationTest testCase);
|
void inject(IntroductionIntegrationTest testCase);
|
||||||
|
|
||||||
@@ -83,16 +79,12 @@ interface IntroductionIntegrationTestComponent {
|
|||||||
|
|
||||||
TransportPropertyManager getTransportPropertyManager();
|
TransportPropertyManager getTransportPropertyManager();
|
||||||
|
|
||||||
MessageTracker getMessageTracker();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
SyncSessionFactory getSyncSessionFactory();
|
||||||
|
|
||||||
/* the following methods are only needed to manually construct messages */
|
/* the following methods are only needed to manually construct messages */
|
||||||
|
|
||||||
DatabaseComponent getDatabaseComponent();
|
DatabaseComponent getDatabaseComponent();
|
||||||
|
|
||||||
ClientHelper getClientHelper();
|
|
||||||
|
|
||||||
MessageSender getMessageSender();
|
MessageSender getMessageSender();
|
||||||
|
|
||||||
IntroductionGroupFactory getIntroductionGroupFactory();
|
IntroductionGroupFactory getIntroductionGroupFactory();
|
||||||
@@ -6,14 +6,14 @@ import org.briarproject.api.crypto.PrivateKey;
|
|||||||
import org.briarproject.api.forum.ForumConstants;
|
import org.briarproject.api.forum.ForumConstants;
|
||||||
import org.briarproject.api.forum.ForumPost;
|
import org.briarproject.api.forum.ForumPost;
|
||||||
import org.briarproject.api.forum.ForumPostFactory;
|
import org.briarproject.api.forum.ForumPostFactory;
|
||||||
|
import org.briarproject.api.identity.Author;
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
import org.briarproject.api.identity.AuthorFactory;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.messaging.MessagingConstants;
|
||||||
import org.briarproject.api.messaging.PrivateMessage;
|
import org.briarproject.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.api.messaging.PrivateMessageFactory;
|
import org.briarproject.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.system.SystemModule;
|
import org.briarproject.system.SystemModule;
|
||||||
import org.briarproject.util.StringUtils;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -48,14 +48,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
// Create a maximum-length private message
|
// Create a maximum-length private message
|
||||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||||
long timestamp = Long.MAX_VALUE;
|
long timestamp = Long.MAX_VALUE;
|
||||||
String body =
|
MessageId parent = new MessageId(TestUtils.getRandomId());
|
||||||
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
|
String contentType = TestUtils.getRandomString(
|
||||||
|
MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
|
||||||
|
byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
|
||||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||||
groupId, timestamp, body);
|
groupId, timestamp, parent, contentType, body);
|
||||||
// Check the size of the serialised message
|
// Check the size of the serialised message
|
||||||
int length = message.getMessage().getRaw().length;
|
int length = message.getMessage().getRaw().length;
|
||||||
assertTrue(
|
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
|
||||||
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
+ MessagingConstants.MAX_CONTENT_TYPE_LENGTH
|
||||||
|
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||||
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,17 +68,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
String authorName = TestUtils.getRandomString(
|
String authorName = TestUtils.getRandomString(
|
||||||
MAX_AUTHOR_NAME_LENGTH);
|
MAX_AUTHOR_NAME_LENGTH);
|
||||||
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
|
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
|
||||||
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
|
Author author = authorFactory.createAuthor(authorName, authorPublic);
|
||||||
LocalAuthor author = authorFactory
|
|
||||||
.createLocalAuthor(authorName, authorPublic,
|
|
||||||
privateKey.getEncoded());
|
|
||||||
// Create a maximum-length forum post
|
// Create a maximum-length forum post
|
||||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
||||||
long timestamp = Long.MAX_VALUE;
|
long timestamp = Long.MAX_VALUE;
|
||||||
MessageId parent = new MessageId(TestUtils.getRandomId());
|
MessageId parent = new MessageId(TestUtils.getRandomId());
|
||||||
String body = TestUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
|
String contentType = TestUtils.getRandomString(
|
||||||
ForumPost post = forumPostFactory.createPost(groupId,
|
ForumConstants.MAX_CONTENT_TYPE_LENGTH);
|
||||||
timestamp, parent, author, body);
|
byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH];
|
||||||
|
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
|
||||||
|
ForumPost post = forumPostFactory.createPseudonymousPost(groupId,
|
||||||
|
timestamp, parent, author, contentType, body, privateKey);
|
||||||
// Check the size of the serialised message
|
// Check the size of the serialised message
|
||||||
int length = post.getMessage().getRaw().length;
|
int length = post.getMessage().getRaw().length;
|
||||||
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
|
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
|
||||||
|
|||||||
@@ -1,838 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
|
||||||
|
|
||||||
import org.briarproject.api.clients.ClientHelper;
|
|
||||||
import org.briarproject.api.clients.ContactGroupFactory;
|
|
||||||
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.api.data.BdfList;
|
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.db.Transaction;
|
|
||||||
import org.briarproject.api.event.Event;
|
|
||||||
import org.briarproject.api.event.EventListener;
|
|
||||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.api.privategroup.GroupMember;
|
|
||||||
import org.briarproject.api.privategroup.GroupMessage;
|
|
||||||
import org.briarproject.api.privategroup.GroupMessageFactory;
|
|
||||||
import org.briarproject.api.privategroup.GroupMessageHeader;
|
|
||||||
import org.briarproject.api.privategroup.JoinMessageHeader;
|
|
||||||
import org.briarproject.api.privategroup.PrivateGroup;
|
|
||||||
import org.briarproject.api.privategroup.PrivateGroupFactory;
|
|
||||||
import org.briarproject.api.privategroup.PrivateGroupManager;
|
|
||||||
import org.briarproject.api.privategroup.invitation.GroupInvitationFactory;
|
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
import org.briarproject.api.sync.MessageId;
|
|
||||||
import org.briarproject.api.sync.SyncSession;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
|
||||||
import org.briarproject.contact.ContactModule;
|
|
||||||
import org.briarproject.crypto.CryptoModule;
|
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
|
||||||
import org.briarproject.privategroup.PrivateGroupModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
|
||||||
import org.briarproject.sync.SyncModule;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
|
||||||
import static org.briarproject.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.api.identity.Author.Status.VERIFIED;
|
|
||||||
import static org.briarproject.api.privategroup.Visibility.INVISIBLE;
|
|
||||||
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_CONTACT;
|
|
||||||
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_US;
|
|
||||||
import static org.briarproject.api.privategroup.Visibility.VISIBLE;
|
|
||||||
import static org.briarproject.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
|
|
||||||
import static org.briarproject.api.sync.Group.Visibility.SHARED;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class PrivateGroupManagerTest extends BriarIntegrationTest {
|
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1,
|
|
||||||
lifecycleManager2;
|
|
||||||
private SyncSessionFactory sync0, sync1, sync2;
|
|
||||||
private PrivateGroupManager groupManager0, groupManager1, groupManager2;
|
|
||||||
private ContactManager contactManager0, contactManager1, contactManager2;
|
|
||||||
private ContactId contactId01, contactId02, contactId1, contactId2;
|
|
||||||
private IdentityManager identityManager0, identityManager1,
|
|
||||||
identityManager2;
|
|
||||||
private LocalAuthor author0, author1, author2;
|
|
||||||
private DatabaseComponent db0, db1, db2;
|
|
||||||
private PrivateGroup privateGroup0;
|
|
||||||
private GroupId groupId0;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Clock clock;
|
|
||||||
@Inject
|
|
||||||
AuthorFactory authorFactory;
|
|
||||||
@Inject
|
|
||||||
ClientHelper clientHelper;
|
|
||||||
@Inject
|
|
||||||
CryptoComponent crypto;
|
|
||||||
@Inject
|
|
||||||
ContactGroupFactory contactGroupFactory;
|
|
||||||
@Inject
|
|
||||||
PrivateGroupFactory privateGroupFactory;
|
|
||||||
@Inject
|
|
||||||
GroupMessageFactory groupMessageFactory;
|
|
||||||
@Inject
|
|
||||||
GroupInvitationFactory groupInvitationFactory;
|
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
|
||||||
private volatile Waiter validationWaiter;
|
|
||||||
private volatile Waiter deliveryWaiter;
|
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
|
||||||
private final SecretKey master = TestUtils.getSecretKey();
|
|
||||||
private final int TIMEOUT = 15000;
|
|
||||||
private final String AUTHOR0 = "Author 0";
|
|
||||||
private final String AUTHOR1 = "Author 1";
|
|
||||||
private final String AUTHOR2 = "Author 2";
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(PrivateGroupManagerTest.class.getName());
|
|
||||||
|
|
||||||
private PrivateGroupManagerTestComponent t0, t1, t2;
|
|
||||||
|
|
||||||
@Rule
|
|
||||||
public ExpectedException thrown = ExpectedException.none();
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
PrivateGroupManagerTestComponent component =
|
|
||||||
DaggerPrivateGroupManagerTestComponent.builder().build();
|
|
||||||
component.inject(this);
|
|
||||||
|
|
||||||
assertTrue(testDir.mkdirs());
|
|
||||||
File t0Dir = new File(testDir, AUTHOR0);
|
|
||||||
t0 = DaggerPrivateGroupManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
|
|
||||||
injectEagerSingletons(t0);
|
|
||||||
File t1Dir = new File(testDir, AUTHOR1);
|
|
||||||
t1 = DaggerPrivateGroupManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
|
|
||||||
injectEagerSingletons(t1);
|
|
||||||
File t2Dir = new File(testDir, AUTHOR2);
|
|
||||||
t2 = DaggerPrivateGroupManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t2Dir)).build();
|
|
||||||
injectEagerSingletons(t2);
|
|
||||||
|
|
||||||
identityManager0 = t0.getIdentityManager();
|
|
||||||
identityManager1 = t1.getIdentityManager();
|
|
||||||
identityManager2 = t2.getIdentityManager();
|
|
||||||
contactManager0 = t0.getContactManager();
|
|
||||||
contactManager1 = t1.getContactManager();
|
|
||||||
contactManager2 = t2.getContactManager();
|
|
||||||
db0 = t0.getDatabaseComponent();
|
|
||||||
db1 = t1.getDatabaseComponent();
|
|
||||||
db2 = t2.getDatabaseComponent();
|
|
||||||
groupManager0 = t0.getPrivateGroupManager();
|
|
||||||
groupManager1 = t1.getPrivateGroupManager();
|
|
||||||
groupManager2 = t2.getPrivateGroupManager();
|
|
||||||
sync0 = t0.getSyncSessionFactory();
|
|
||||||
sync1 = t1.getSyncSessionFactory();
|
|
||||||
sync2 = t2.getSyncSessionFactory();
|
|
||||||
|
|
||||||
// initialize waiters fresh for each test
|
|
||||||
validationWaiter = new Waiter();
|
|
||||||
deliveryWaiter = new Waiter();
|
|
||||||
|
|
||||||
startLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSendingMessage() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// create and add test message
|
|
||||||
long time = clock.currentTimeMillis();
|
|
||||||
String body = "This is a test message!";
|
|
||||||
MessageId previousMsgId =
|
|
||||||
groupManager0.getPreviousMsgId(groupId0);
|
|
||||||
GroupMessage msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, time, null, author0, body,
|
|
||||||
previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
assertEquals(msg.getMessage().getId(),
|
|
||||||
groupManager0.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message arrived as expected
|
|
||||||
Collection<GroupMessageHeader> headers =
|
|
||||||
groupManager1.getHeaders(groupId0);
|
|
||||||
assertEquals(3, headers.size());
|
|
||||||
GroupMessageHeader header = null;
|
|
||||||
for (GroupMessageHeader h : headers) {
|
|
||||||
if (!(h instanceof JoinMessageHeader)) {
|
|
||||||
header = h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertTrue(header != null);
|
|
||||||
assertFalse(header.isRead());
|
|
||||||
assertEquals(author0, header.getAuthor());
|
|
||||||
assertEquals(time, header.getTimestamp());
|
|
||||||
assertEquals(VERIFIED, header.getAuthorStatus());
|
|
||||||
assertEquals(body, groupManager1.getMessageBody(header.getId()));
|
|
||||||
GroupCount count = groupManager1.getGroupCount(groupId0);
|
|
||||||
assertEquals(2, count.getUnreadCount());
|
|
||||||
assertEquals(time, count.getLatestMsgTime());
|
|
||||||
assertEquals(3, count.getMsgCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMessageWithWrongPreviousMsgId() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// create and add test message with no previousMsgId
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
GroupMessage msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
|
||||||
author0, "test", null);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
// create and add test message with random previousMsgId
|
|
||||||
MessageId previousMsgId = new MessageId(TestUtils.getRandomId());
|
|
||||||
msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
|
||||||
author0, "test", previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
// create and add test message with wrong previousMsgId
|
|
||||||
previousMsgId = groupManager1.getPreviousMsgId(groupId0);
|
|
||||||
msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
|
|
||||||
author0, "test", previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMessageWithWrongParentMsgId() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// create and add test message with random parentMsgId
|
|
||||||
MessageId parentMsgId = new MessageId(TestUtils.getRandomId());
|
|
||||||
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
|
|
||||||
GroupMessage msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(),
|
|
||||||
parentMsgId, author0, "test", previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
// create and add test message with wrong parentMsgId
|
|
||||||
parentMsgId = previousMsgId;
|
|
||||||
msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, clock.currentTimeMillis(),
|
|
||||||
parentMsgId, author0, "test", previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testMessageWithWrongTimestamp() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// create and add test message with wrong timestamp
|
|
||||||
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
|
|
||||||
GroupMessage msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, 42, null, author0, "test",
|
|
||||||
previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(2, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
// create and add test message with good timestamp
|
|
||||||
long time = clock.currentTimeMillis();
|
|
||||||
msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, time, null, author0, "test",
|
|
||||||
previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(3, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
// create and add test message with same timestamp as previous message
|
|
||||||
previousMsgId = msg.getMessage().getId();
|
|
||||||
msg = groupMessageFactory
|
|
||||||
.createGroupMessage(groupId0, time, previousMsgId, author0,
|
|
||||||
"test2", previousMsgId);
|
|
||||||
groupManager0.addLocalMessage(msg);
|
|
||||||
|
|
||||||
// sync test message
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that message did not arrive
|
|
||||||
assertEquals(3, groupManager1.getHeaders(groupId0).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrongJoinMessages1() throws Exception {
|
|
||||||
addDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
listenToEvents();
|
|
||||||
|
|
||||||
// author0 joins privateGroup0 with wrong join message
|
|
||||||
long joinTime = clock.currentTimeMillis();
|
|
||||||
GroupMessage joinMsg0 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
|
|
||||||
joinTime, getRandomBytes(12));
|
|
||||||
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
|
|
||||||
assertEquals(joinMsg0.getMessage().getId(),
|
|
||||||
groupManager0.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// share the group with 1
|
|
||||||
Transaction txn0 = db0.startTransaction(false);
|
|
||||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
|
||||||
db0.commitTransaction(txn0);
|
|
||||||
db0.endTransaction(txn0);
|
|
||||||
|
|
||||||
// author1 joins privateGroup0 with wrong timestamp
|
|
||||||
joinTime = clock.currentTimeMillis();
|
|
||||||
long inviteTime = joinTime;
|
|
||||||
Contact c1 = contactManager0.getContact(contactId1);
|
|
||||||
byte[] creatorSignature = groupInvitationFactory
|
|
||||||
.signInvitation(c1, privateGroup0.getId(), inviteTime,
|
|
||||||
author0.getPrivateKey());
|
|
||||||
GroupMessage joinMsg1 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
|
|
||||||
inviteTime, creatorSignature);
|
|
||||||
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
|
|
||||||
assertEquals(joinMsg1.getMessage().getId(),
|
|
||||||
groupManager1.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// share the group with 0
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
|
|
||||||
SHARED);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
|
|
||||||
// sync join messages
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that 0 never joined the group from 1's perspective
|
|
||||||
assertEquals(1, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
sync1To0();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that 1 never joined the group from 0's perspective
|
|
||||||
assertEquals(1, groupManager0.getHeaders(groupId0).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testWrongJoinMessages2() throws Exception {
|
|
||||||
addDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
listenToEvents();
|
|
||||||
|
|
||||||
// author0 joins privateGroup0 with wrong member's join message
|
|
||||||
long joinTime = clock.currentTimeMillis();
|
|
||||||
long inviteTime = joinTime - 1;
|
|
||||||
BdfList toSign = groupInvitationFactory
|
|
||||||
.createInviteToken(author0.getId(), author0.getId(),
|
|
||||||
privateGroup0.getId(), inviteTime);
|
|
||||||
byte[] creatorSignature = clientHelper
|
|
||||||
.sign(SIGNING_LABEL_INVITE, toSign, author0.getPrivateKey());
|
|
||||||
// join message should not include invite time and creator's signature
|
|
||||||
GroupMessage joinMsg0 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
|
|
||||||
inviteTime, creatorSignature);
|
|
||||||
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
|
|
||||||
assertEquals(joinMsg0.getMessage().getId(),
|
|
||||||
groupManager0.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// share the group with 1
|
|
||||||
Transaction txn0 = db0.startTransaction(false);
|
|
||||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
|
||||||
db0.commitTransaction(txn0);
|
|
||||||
db0.endTransaction(txn0);
|
|
||||||
|
|
||||||
// author1 joins privateGroup0 with wrong signature in join message
|
|
||||||
joinTime = clock.currentTimeMillis();
|
|
||||||
inviteTime = joinTime - 1;
|
|
||||||
// signature uses joiner's key, not creator's key
|
|
||||||
Contact c1 = contactManager0.getContact(contactId1);
|
|
||||||
creatorSignature = groupInvitationFactory
|
|
||||||
.signInvitation(c1, privateGroup0.getId(), inviteTime,
|
|
||||||
author1.getPrivateKey());
|
|
||||||
GroupMessage joinMsg1 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
|
|
||||||
inviteTime, creatorSignature);
|
|
||||||
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
|
|
||||||
assertEquals(joinMsg1.getMessage().getId(),
|
|
||||||
groupManager1.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// share the group with 0
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(), SHARED);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
|
|
||||||
// sync join messages
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that 0 never joined the group from 1's perspective
|
|
||||||
assertEquals(1, groupManager1.getHeaders(groupId0).size());
|
|
||||||
|
|
||||||
sync1To0();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// assert that 1 never joined the group from 0's perspective
|
|
||||||
assertEquals(1, groupManager0.getHeaders(groupId0).size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetMembers() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
|
|
||||||
assertEquals(2, members0.size());
|
|
||||||
for (GroupMember m : members0) {
|
|
||||||
if (m.getAuthor().equals(author0)) {
|
|
||||||
assertEquals(VISIBLE, m.getVisibility());
|
|
||||||
} else {
|
|
||||||
assertEquals(author1, m.getAuthor());
|
|
||||||
assertEquals(VISIBLE, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
|
|
||||||
assertEquals(2, members1.size());
|
|
||||||
for (GroupMember m : members1) {
|
|
||||||
if (m.getAuthor().equals(author1)) {
|
|
||||||
assertEquals(VISIBLE, m.getVisibility());
|
|
||||||
} else {
|
|
||||||
assertEquals(author0, m.getAuthor());
|
|
||||||
assertEquals(VISIBLE, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJoinMessages() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
Collection<GroupMessageHeader> headers0 =
|
|
||||||
groupManager0.getHeaders(groupId0);
|
|
||||||
for (GroupMessageHeader h : headers0) {
|
|
||||||
if (h instanceof JoinMessageHeader) {
|
|
||||||
JoinMessageHeader j = (JoinMessageHeader) h;
|
|
||||||
// all relationships of the creator are visible
|
|
||||||
assertEquals(VISIBLE, j.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<GroupMessageHeader> headers1 =
|
|
||||||
groupManager1.getHeaders(groupId0);
|
|
||||||
for (GroupMessageHeader h : headers1) {
|
|
||||||
if (h instanceof JoinMessageHeader) {
|
|
||||||
JoinMessageHeader j = (JoinMessageHeader) h;
|
|
||||||
if (h.getAuthor().equals(author1))
|
|
||||||
// we are visible to ourselves
|
|
||||||
assertEquals(VISIBLE, j.getVisibility());
|
|
||||||
else
|
|
||||||
// our relationship to the creator is visible
|
|
||||||
assertEquals(VISIBLE, j.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testRevealingRelationships() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// share the group with 2
|
|
||||||
Transaction txn0 = db0.startTransaction(false);
|
|
||||||
db0.setGroupVisibility(txn0, contactId2, privateGroup0.getId(), SHARED);
|
|
||||||
db0.commitTransaction(txn0);
|
|
||||||
db0.endTransaction(txn0);
|
|
||||||
|
|
||||||
// author2 joins privateGroup0
|
|
||||||
long joinTime = clock.currentTimeMillis();
|
|
||||||
long inviteTime = joinTime - 1;
|
|
||||||
Contact c2 = contactManager0.getContact(contactId2);
|
|
||||||
byte[] creatorSignature = groupInvitationFactory
|
|
||||||
.signInvitation(c2, privateGroup0.getId(), inviteTime,
|
|
||||||
author0.getPrivateKey());
|
|
||||||
GroupMessage joinMsg2 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author2,
|
|
||||||
inviteTime, creatorSignature);
|
|
||||||
Transaction txn2 = db2.startTransaction(false);
|
|
||||||
groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false);
|
|
||||||
|
|
||||||
// share the group with 0
|
|
||||||
db2.setGroupVisibility(txn2, contactId01, privateGroup0.getId(),
|
|
||||||
SHARED);
|
|
||||||
db2.commitTransaction(txn2);
|
|
||||||
db2.endTransaction(txn2);
|
|
||||||
|
|
||||||
// sync join messages
|
|
||||||
deliverMessage(sync2, contactId2, sync0, contactId02, "2 to 0");
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
deliverMessage(sync0, contactId02, sync2, contactId2, "0 to 2");
|
|
||||||
deliveryWaiter.await(TIMEOUT, 2);
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// check that everybody sees everybody else as joined
|
|
||||||
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
|
|
||||||
assertEquals(3, members0.size());
|
|
||||||
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
|
|
||||||
assertEquals(3, members1.size());
|
|
||||||
Collection<GroupMember> members2 = groupManager2.getMembers(groupId0);
|
|
||||||
assertEquals(3, members2.size());
|
|
||||||
|
|
||||||
// assert that contact relationship is not revealed initially
|
|
||||||
for (GroupMember m : members1) {
|
|
||||||
if (m.getAuthor().equals(author2)) {
|
|
||||||
assertEquals(INVISIBLE, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (GroupMember m : members2) {
|
|
||||||
if (m.getAuthor().equals(author1)) {
|
|
||||||
assertEquals(INVISIBLE, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reveal contact relationship
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
groupManager1
|
|
||||||
.relationshipRevealed(txn1, groupId0, author2.getId(), false);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
txn2 = db2.startTransaction(false);
|
|
||||||
groupManager2
|
|
||||||
.relationshipRevealed(txn2, groupId0, author1.getId(), true);
|
|
||||||
db2.commitTransaction(txn2);
|
|
||||||
db2.endTransaction(txn2);
|
|
||||||
|
|
||||||
// assert that contact relationship is now revealed properly
|
|
||||||
members1 = groupManager1.getMembers(groupId0);
|
|
||||||
for (GroupMember m : members1) {
|
|
||||||
if (m.getAuthor().equals(author2)) {
|
|
||||||
assertEquals(REVEALED_BY_US, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
members2 = groupManager2.getMembers(groupId0);
|
|
||||||
for (GroupMember m : members2) {
|
|
||||||
if (m.getAuthor().equals(author1)) {
|
|
||||||
assertEquals(REVEALED_BY_CONTACT, m.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assert that join messages reflect revealed relationship
|
|
||||||
Collection<GroupMessageHeader> headers1 =
|
|
||||||
groupManager1.getHeaders(groupId0);
|
|
||||||
for (GroupMessageHeader h : headers1) {
|
|
||||||
if (h instanceof JoinMessageHeader) {
|
|
||||||
JoinMessageHeader j = (JoinMessageHeader) h;
|
|
||||||
if (h.getAuthor().equals(author2))
|
|
||||||
// 1 revealed the relationship to 2
|
|
||||||
assertEquals(REVEALED_BY_US, j.getVisibility());
|
|
||||||
else
|
|
||||||
// 1's other relationship (to 1 and creator) are visible
|
|
||||||
assertEquals(VISIBLE, j.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Collection<GroupMessageHeader> headers2 =
|
|
||||||
groupManager2.getHeaders(groupId0);
|
|
||||||
for (GroupMessageHeader h : headers2) {
|
|
||||||
if (h instanceof JoinMessageHeader) {
|
|
||||||
JoinMessageHeader j = (JoinMessageHeader) h;
|
|
||||||
if (h.getAuthor().equals(author1))
|
|
||||||
// 2's relationship was revealed by 1
|
|
||||||
assertEquals(REVEALED_BY_CONTACT, j.getVisibility());
|
|
||||||
else
|
|
||||||
// 2's other relationship (to 2 and creator) are visible
|
|
||||||
assertEquals(VISIBLE, j.getVisibility());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDissolveGroup() throws Exception {
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// group is not dissolved initially
|
|
||||||
assertFalse(groupManager1.isDissolved(groupId0));
|
|
||||||
|
|
||||||
// creator dissolves group
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
groupManager1.markGroupDissolved(txn1, groupId0);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
|
|
||||||
// group is dissolved now
|
|
||||||
assertTrue(groupManager1.isDissolved(groupId0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
stopLifecycles();
|
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Listener implements EventListener {
|
|
||||||
@Override
|
|
||||||
public void eventOccurred(Event e) {
|
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
|
||||||
if (!event.isLocal()) {
|
|
||||||
if (event.getState() == DELIVERED) {
|
|
||||||
LOG.info("Delivered new message");
|
|
||||||
deliveryWaiter.resume();
|
|
||||||
} else if (event.getState() == INVALID ||
|
|
||||||
event.getState() == PENDING) {
|
|
||||||
LOG.info("Validated new " + event.getState().name() +
|
|
||||||
" message");
|
|
||||||
validationWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defaultInit() throws Exception {
|
|
||||||
addDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
listenToEvents();
|
|
||||||
addGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultIdentities() throws DbException {
|
|
||||||
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
|
|
||||||
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
|
|
||||||
author0 = authorFactory
|
|
||||||
.createLocalAuthor(AUTHOR0, publicKey0, privateKey0);
|
|
||||||
identityManager0.registerLocalAuthor(author0);
|
|
||||||
privateGroup0 =
|
|
||||||
privateGroupFactory.createPrivateGroup("Testgroup", author0);
|
|
||||||
groupId0 = privateGroup0.getId();
|
|
||||||
|
|
||||||
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
|
|
||||||
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
|
|
||||||
author1 = authorFactory
|
|
||||||
.createLocalAuthor(AUTHOR1, publicKey1, privateKey1);
|
|
||||||
identityManager1.registerLocalAuthor(author1);
|
|
||||||
|
|
||||||
KeyPair keyPair2 = crypto.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey2 = keyPair2.getPublic().getEncoded();
|
|
||||||
byte[] privateKey2 = keyPair2.getPrivate().getEncoded();
|
|
||||||
author2 = authorFactory
|
|
||||||
.createLocalAuthor(AUTHOR2, publicKey2, privateKey2);
|
|
||||||
identityManager2.registerLocalAuthor(author2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
|
||||||
// creator adds invitee as contact
|
|
||||||
contactId1 = contactManager0
|
|
||||||
.addContact(author1, author0.getId(), master,
|
|
||||||
clock.currentTimeMillis(), true, true, true);
|
|
||||||
// invitee adds creator back
|
|
||||||
contactId01 = contactManager1
|
|
||||||
.addContact(author0, author1.getId(), master,
|
|
||||||
clock.currentTimeMillis(), true, true, true);
|
|
||||||
// creator adds invitee as contact
|
|
||||||
contactId2 = contactManager0
|
|
||||||
.addContact(author2, author0.getId(), master,
|
|
||||||
clock.currentTimeMillis(), true, true, true);
|
|
||||||
// invitee adds creator back
|
|
||||||
contactId02 = contactManager2
|
|
||||||
.addContact(author0, author2.getId(), master,
|
|
||||||
clock.currentTimeMillis(), true, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listenToEvents() {
|
|
||||||
Listener listener0 = new Listener();
|
|
||||||
t0.getEventBus().addListener(listener0);
|
|
||||||
Listener listener1 = new Listener();
|
|
||||||
t1.getEventBus().addListener(listener1);
|
|
||||||
Listener listener2 = new Listener();
|
|
||||||
t2.getEventBus().addListener(listener2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addGroup() throws Exception {
|
|
||||||
// author0 joins privateGroup0
|
|
||||||
long joinTime = clock.currentTimeMillis();
|
|
||||||
GroupMessage joinMsg0 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author0);
|
|
||||||
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
|
|
||||||
assertEquals(joinMsg0.getMessage().getId(),
|
|
||||||
groupManager0.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// share the group with 1
|
|
||||||
Transaction txn0 = db0.startTransaction(false);
|
|
||||||
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
|
|
||||||
db0.commitTransaction(txn0);
|
|
||||||
db0.endTransaction(txn0);
|
|
||||||
|
|
||||||
// author1 joins privateGroup0
|
|
||||||
joinTime = clock.currentTimeMillis();
|
|
||||||
long inviteTime = joinTime - 1;
|
|
||||||
Contact c1 = contactManager0.getContact(contactId1);
|
|
||||||
byte[] creatorSignature = groupInvitationFactory
|
|
||||||
.signInvitation(c1, privateGroup0.getId(), inviteTime,
|
|
||||||
author0.getPrivateKey());
|
|
||||||
GroupMessage joinMsg1 = groupMessageFactory
|
|
||||||
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
|
|
||||||
inviteTime, creatorSignature);
|
|
||||||
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
|
|
||||||
|
|
||||||
// share the group with 0
|
|
||||||
Transaction txn1 = db1.startTransaction(false);
|
|
||||||
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
|
|
||||||
SHARED);
|
|
||||||
db1.commitTransaction(txn1);
|
|
||||||
db1.endTransaction(txn1);
|
|
||||||
assertEquals(joinMsg1.getMessage().getId(),
|
|
||||||
groupManager1.getPreviousMsgId(groupId0));
|
|
||||||
|
|
||||||
// sync join messages
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync0To1() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync0, contactId01, sync1, contactId1, "0 to 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync1To0() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync1, contactId1, sync0, contactId01, "1 to 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
|
||||||
SyncSessionFactory toSync, ContactId toId, String debug)
|
|
||||||
throws IOException, TimeoutException {
|
|
||||||
|
|
||||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
// Create an outgoing sync session
|
|
||||||
SyncSession sessionFrom =
|
|
||||||
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
|
||||||
// Write whatever needs to be written
|
|
||||||
sessionFrom.run();
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
|
||||||
// Create an incoming sync session
|
|
||||||
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
|
|
||||||
// Read whatever needs to be read
|
|
||||||
sessionTo.run();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startLifecycles() throws InterruptedException {
|
|
||||||
// Start the lifecycle manager and wait for it to finish
|
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
|
||||||
lifecycleManager2 = t2.getLifecycleManager();
|
|
||||||
lifecycleManager0.startServices(AUTHOR0);
|
|
||||||
lifecycleManager1.startServices(AUTHOR1);
|
|
||||||
lifecycleManager2.startServices(AUTHOR2);
|
|
||||||
lifecycleManager0.waitForStartup();
|
|
||||||
lifecycleManager1.waitForStartup();
|
|
||||||
lifecycleManager2.waitForStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopLifecycles() throws InterruptedException {
|
|
||||||
// Clean up
|
|
||||||
lifecycleManager0.stopServices();
|
|
||||||
lifecycleManager1.stopServices();
|
|
||||||
lifecycleManager2.stopServices();
|
|
||||||
lifecycleManager0.waitForShutdown();
|
|
||||||
lifecycleManager1.waitForShutdown();
|
|
||||||
lifecycleManager2.waitForShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectEagerSingletons(
|
|
||||||
PrivateGroupManagerTestComponent component) {
|
|
||||||
component.inject(new LifecycleModule.EagerSingletons());
|
|
||||||
component.inject(new PrivateGroupModule.EagerSingletons());
|
|
||||||
component.inject(new CryptoModule.EagerSingletons());
|
|
||||||
component.inject(new ContactModule.EagerSingletons());
|
|
||||||
component.inject(new TransportModule.EagerSingletons());
|
|
||||||
component.inject(new SyncModule.EagerSingletons());
|
|
||||||
component.inject(new PropertiesModule.EagerSingletons());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
|
||||||
import org.briarproject.api.event.EventBus;
|
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.api.privategroup.PrivateGroupManager;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
import org.briarproject.clients.ClientsModule;
|
|
||||||
import org.briarproject.contact.ContactModule;
|
|
||||||
import org.briarproject.crypto.CryptoModule;
|
|
||||||
import org.briarproject.data.DataModule;
|
|
||||||
import org.briarproject.db.DatabaseModule;
|
|
||||||
import org.briarproject.event.EventModule;
|
|
||||||
import org.briarproject.identity.IdentityModule;
|
|
||||||
import org.briarproject.lifecycle.LifecycleModule;
|
|
||||||
import org.briarproject.messaging.MessagingModule;
|
|
||||||
import org.briarproject.privategroup.PrivateGroupModule;
|
|
||||||
import org.briarproject.privategroup.invitation.GroupInvitationModule;
|
|
||||||
import org.briarproject.properties.PropertiesModule;
|
|
||||||
import org.briarproject.sharing.SharingModule;
|
|
||||||
import org.briarproject.sync.SyncModule;
|
|
||||||
import org.briarproject.system.SystemModule;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import dagger.Component;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Component(modules = {
|
|
||||||
TestDatabaseModule.class,
|
|
||||||
TestPluginsModule.class,
|
|
||||||
TestSeedProviderModule.class,
|
|
||||||
ClientsModule.class,
|
|
||||||
ContactModule.class,
|
|
||||||
CryptoModule.class,
|
|
||||||
DataModule.class,
|
|
||||||
DatabaseModule.class,
|
|
||||||
EventModule.class,
|
|
||||||
MessagingModule.class,
|
|
||||||
PrivateGroupModule.class,
|
|
||||||
GroupInvitationModule.class,
|
|
||||||
IdentityModule.class,
|
|
||||||
LifecycleModule.class,
|
|
||||||
PropertiesModule.class,
|
|
||||||
SharingModule.class,
|
|
||||||
SyncModule.class,
|
|
||||||
SystemModule.class,
|
|
||||||
TransportModule.class
|
|
||||||
})
|
|
||||||
interface PrivateGroupManagerTestComponent {
|
|
||||||
|
|
||||||
void inject(PrivateGroupManagerTest testCase);
|
|
||||||
|
|
||||||
void inject(ContactModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(CryptoModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(PrivateGroupModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(LifecycleModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(PropertiesModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(SyncModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(TransportModule.EagerSingletons init);
|
|
||||||
|
|
||||||
LifecycleManager getLifecycleManager();
|
|
||||||
|
|
||||||
EventBus getEventBus();
|
|
||||||
|
|
||||||
IdentityManager getIdentityManager();
|
|
||||||
|
|
||||||
ContactManager getContactManager();
|
|
||||||
|
|
||||||
PrivateGroupManager getPrivateGroupManager();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
|
||||||
|
|
||||||
DatabaseComponent getDatabaseComponent();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -43,9 +43,6 @@ import static org.junit.Assert.assertTrue;
|
|||||||
|
|
||||||
public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||||
|
|
||||||
private final static String ALICE = "Alice";
|
|
||||||
private final static String BOB = "Bob";
|
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
private final File testDir = TestUtils.getTestDirectory();
|
||||||
private final File aliceDir = new File(testDir, "alice");
|
private final File aliceDir = new File(testDir, "alice");
|
||||||
private final File bobDir = new File(testDir, "bob");
|
private final File bobDir = new File(testDir, "bob");
|
||||||
@@ -72,7 +69,6 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
read(write());
|
read(write());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private byte[] write() throws Exception {
|
private byte[] write() throws Exception {
|
||||||
// Instantiate Alice's services
|
// Instantiate Alice's services
|
||||||
LifecycleManager lifecycleManager = alice.getLifecycleManager();
|
LifecycleManager lifecycleManager = alice.getLifecycleManager();
|
||||||
@@ -87,23 +83,23 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
|
SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
|
||||||
|
|
||||||
// Start the lifecycle manager
|
// Start the lifecycle manager
|
||||||
lifecycleManager.startServices(null);
|
lifecycleManager.startServices();
|
||||||
lifecycleManager.waitForStartup();
|
lifecycleManager.waitForStartup();
|
||||||
// Add an identity for Alice
|
// Add an identity for Alice
|
||||||
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
|
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||||
identityManager.registerLocalAuthor(aliceAuthor);
|
identityManager.addLocalAuthor(aliceAuthor);
|
||||||
// Add Bob as a contact
|
// Add Bob as a contact
|
||||||
Author bobAuthor = new Author(bobId, BOB,
|
Author bobAuthor = new Author(bobId, "Bob",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(bobAuthor,
|
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
||||||
aliceAuthor.getId(), master, timestamp, true, true, true);
|
master, timestamp, true, true);
|
||||||
|
|
||||||
// Send Bob a message
|
// Send Bob a message
|
||||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||||
String body = "Hi Bob!";
|
byte[] body = "Hi Bob!".getBytes("UTF-8");
|
||||||
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
PrivateMessage message = privateMessageFactory.createPrivateMessage(
|
||||||
groupId, timestamp, body);
|
groupId, timestamp, null, "text/plain", body);
|
||||||
messagingManager.addLocalMessage(message);
|
messagingManager.addLocalMessage(message);
|
||||||
// Get a stream context
|
// Get a stream context
|
||||||
StreamContext ctx = keyManager.getStreamContext(contactId,
|
StreamContext ctx = keyManager.getStreamContext(contactId,
|
||||||
@@ -140,17 +136,18 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
bob.getMessagingManager();
|
bob.getMessagingManager();
|
||||||
|
|
||||||
// Start the lifecyle manager
|
// Start the lifecyle manager
|
||||||
lifecycleManager.startServices(null);
|
lifecycleManager.startServices();
|
||||||
lifecycleManager.waitForStartup();
|
lifecycleManager.waitForStartup();
|
||||||
// Add an identity for Bob
|
// Add an identity for Bob
|
||||||
LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB,
|
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
|
||||||
identityManager.registerLocalAuthor(bobAuthor);
|
identityManager.addLocalAuthor(bobAuthor);
|
||||||
// Add Alice as a contact
|
// Add Alice as a contact
|
||||||
Author aliceAuthor = new Author(aliceId, ALICE,
|
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(aliceAuthor,
|
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
||||||
bobAuthor.getId(), master, timestamp, false, true, true);
|
master, timestamp, false, true);
|
||||||
|
|
||||||
// Set up an event listener
|
// Set up an event listener
|
||||||
MessageListener listener = new MessageListener();
|
MessageListener listener = new MessageListener();
|
||||||
bob.getEventBus().addListener(listener);
|
bob.getEventBus().addListener(listener);
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class SyncIntegrationTest extends BriarTestCase {
|
|||||||
headerKey = TestUtils.getSecretKey();
|
headerKey = TestUtils.getSecretKey();
|
||||||
streamNumber = 123;
|
streamNumber = 123;
|
||||||
// Create a group
|
// Create a group
|
||||||
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
|
ClientId clientId = new ClientId(TestUtils.getRandomId());
|
||||||
byte[] descriptor = new byte[0];
|
byte[] descriptor = new byte[0];
|
||||||
Group group = groupFactory.createGroup(clientId, descriptor);
|
Group group = groupFactory.createGroup(clientId, descriptor);
|
||||||
// Add two messages to the group
|
// Add two messages to the group
|
||||||
@@ -122,7 +122,7 @@ public class SyncIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Create the readers
|
// Create the readers
|
||||||
StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
|
StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
|
||||||
headerKey, streamNumber);
|
headerKey, 0);
|
||||||
InputStream streamReader = streamReaderFactory.createStreamReader(in,
|
InputStream streamReader = streamReaderFactory.createStreamReader(in,
|
||||||
ctx);
|
ctx);
|
||||||
PacketReader packetReader = packetReaderFactory.createPacketReader(
|
PacketReader packetReader = packetReaderFactory.createPacketReader(
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[main]
|
[main]
|
||||||
host = https://www.transifex.com
|
host = https://www.transifex.com
|
||||||
lang_map = pt_BR: pt-rBR, fr_FR: fr
|
lang_map = pt_BR: pt-rBR
|
||||||
|
|
||||||
[briar.stringsxml-5]
|
[briar.stringsxml-5]
|
||||||
file_filter = res/values-<lang>/strings.xml
|
file_filter = res/values-<lang>/strings.xml
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
android:versionName="0.12">
|
android:versionName="0.12">
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="14"
|
android:minSdkVersion="9"
|
||||||
|
|
||||||
android:targetSdkVersion="22"
|
android:targetSdkVersion="22"
|
||||||
tools:overrideLibrary="android.support.v14.preference"
|
tools:overrideLibrary="android.support.v14.preference"
|
||||||
/>
|
/>
|
||||||
@@ -50,9 +51,7 @@
|
|||||||
android:finishOnTaskLaunch="true"
|
android:finishOnTaskLaunch="true"
|
||||||
android:label="@string/crash_report_title"
|
android:label="@string/crash_report_title"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
android:process=":briar_error_handler"
|
android:process=":briar_error_handler">
|
||||||
android:theme="@style/BriarThemeNoActionBar.Default"
|
|
||||||
android:windowSoftInputMode="stateHidden">
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -93,7 +92,7 @@
|
|||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:theme="@style/BriarThemeNoActionBar.Default"
|
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
android:parentActivityName=".android.NavDrawerActivity"
|
||||||
android:windowSoftInputMode="stateHidden|adjustResize">
|
android:windowSoftInputMode="stateHidden">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".android.NavDrawerActivity"
|
android:value=".android.NavDrawerActivity"
|
||||||
@@ -101,70 +100,7 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.privategroup.creation.CreateGroupActivity"
|
android:name=".android.forum.ForumInvitationsActivity"
|
||||||
android:label="@string/groups_create_group_title"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.privategroup.conversation.GroupActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.privategroup.invitation.GroupInvitationActivity"
|
|
||||||
android:label="@string/groups_invitations_title"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.privategroup.memberlist.GroupMemberListActivity"
|
|
||||||
android:label="@string/groups_member_list"
|
|
||||||
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.privategroup.conversation.GroupActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.privategroup.reveal.RevealContactsActivity"
|
|
||||||
android:label="@string/groups_reveal_contacts"
|
|
||||||
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.privategroup.conversation.GroupActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.privategroup.creation.GroupInviteActivity"
|
|
||||||
android:label="@string/groups_invite_members"
|
|
||||||
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.privategroup.conversation.GroupActivity"/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.sharing.ForumInvitationActivity"
|
|
||||||
android:label="@string/forum_invitations_title"
|
android:label="@string/forum_invitations_title"
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
android:parentActivityName=".android.NavDrawerActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
@@ -173,16 +109,6 @@
|
|||||||
/>
|
/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.sharing.BlogInvitationActivity"
|
|
||||||
android:label="@string/blogs_sharing_invitations_title"
|
|
||||||
android:parentActivityName=".android.contact.ConversationActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.contact.ConversationActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.forum.CreateForumActivity"
|
android:name=".android.forum.CreateForumActivity"
|
||||||
android:label="@string/create_forum_title"
|
android:label="@string/create_forum_title"
|
||||||
@@ -197,8 +123,7 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".android.forum.ForumActivity"
|
android:name=".android.forum.ForumActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
android:parentActivityName=".android.NavDrawerActivity">
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".android.NavDrawerActivity"
|
android:value=".android.NavDrawerActivity"
|
||||||
@@ -206,30 +131,8 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.sharing.ShareForumActivity"
|
android:name=".android.forum.ShareForumActivity"
|
||||||
android:label="@string/activity_share_toolbar_header"
|
android:label="@string/forums_share_toolbar_header"
|
||||||
android:parentActivityName=".android.forum.ForumActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.forum.ForumActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.sharing.ShareBlogActivity"
|
|
||||||
android:label="@string/activity_share_toolbar_header"
|
|
||||||
android:parentActivityName=".android.blogs.BlogActivity"
|
|
||||||
android:windowSoftInputMode="adjustResize|stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.blogs.BlogActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.sharing.ForumSharingStatusActivity"
|
|
||||||
android:label="@string/sharing_status"
|
|
||||||
android:parentActivityName=".android.forum.ForumActivity">
|
android:parentActivityName=".android.forum.ForumActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
@@ -238,65 +141,19 @@
|
|||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.sharing.BlogSharingStatusActivity"
|
android:name=".android.forum.ForumSharingStatusActivity"
|
||||||
android:label="@string/sharing_status"
|
android:label="@string/forum_sharing_status"
|
||||||
android:parentActivityName=".android.blogs.BlogActivity">
|
android:parentActivityName=".android.forum.ForumActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value=".android.blogs.BlogActivity"
|
android:value=".android.forum.ForumActivity"
|
||||||
/>
|
/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.blogs.BlogActivity"
|
android:name=".android.identity.CreateIdentityActivity"
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
android:label="@string/new_identity_title"
|
||||||
<meta-data
|
android:windowSoftInputMode="stateVisible">
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.blogs.WriteBlogPostActivity"
|
|
||||||
android:label="@string/blogs_write_blog_post"
|
|
||||||
android:parentActivityName=".android.blogs.BlogActivity"
|
|
||||||
android:windowSoftInputMode="stateVisible|adjustResize">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.blogs.BlogActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.blogs.ReblogActivity"
|
|
||||||
android:label="@string/blogs_reblog_button"
|
|
||||||
android:parentActivityName=".android.blogs.BlogActivity"
|
|
||||||
android:windowSoftInputMode="stateHidden">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.blogs.BlogActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.blogs.RssFeedImportActivity"
|
|
||||||
android:label="@string/blogs_rss_feeds_import"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
|
||||||
android:windowSoftInputMode="stateVisible|adjustResize">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.blogs.RssFeedManageActivity"
|
|
||||||
android:label="@string/blogs_rss_feeds_manage"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -337,7 +194,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.SettingsActivity"
|
android:name=".android.SettingsActivity"
|
||||||
android:label="@string/settings_button"
|
android:label="@string/settings_title"
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
android:parentActivityName=".android.NavDrawerActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
sodipodi:docname="ic_emoji_emoticons.svg">
|
|
||||||
<metadata
|
|
||||||
id="metadata8">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<defs
|
|
||||||
id="defs6" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="1021"
|
|
||||||
id="namedview4"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="4.6354778"
|
|
||||||
inkscape:cx="47.926788"
|
|
||||||
inkscape:cy="24.127496"
|
|
||||||
inkscape:window-x="1440"
|
|
||||||
inkscape:window-y="23"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="svg2" />
|
|
||||||
<path
|
|
||||||
style="fill:#000000;fill-opacity:1"
|
|
||||||
d="m 15.483903,3.8556996 c -0.661546,0.040406 -0.536253,1.2125273 -0.08054,1.6240791 1.361771,1.4519837 1.747379,3.5080793 1.895646,5.4253553 0.109142,2.216286 -0.0846,4.555699 -1.171466,6.533591 -0.361828,0.731167 -1.339597,1.273078 -1.15283,2.195835 0.287109,1.037426 1.187031,0.242862 1.620751,-0.183708 1.991711,-1.742024 2.867744,-4.428018 2.93133,-7.013492 0.02009,-1.918049 -0.231841,-3.9213035 -1.212735,-5.6044037 -0.664187,-1.0906817 -1.39072,-2.2339438 -2.497355,-2.9193489 -0.127976,-0.045915 -0.238296,-0.06368 -0.332802,-0.057908 z M 5.9118212,7.6583077 A 1.3631614,1.3631614 0 0 0 4.54866,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,10.38463 1.3631614,1.3631614 0 0 0 7.2749824,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,7.6583077 Z m 3.0731032,3.0012183 0,2.044742 4.7710646,0 0,-2.044742 -4.7710646,0 z m -3.1496485,3.471136 a 1.3631614,1.3631614 0 0 0 -1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,-1.363161 1.3631614,1.3631614 0 0 0 -1.3631612,-1.363161 z"
|
|
||||||
id="path4142"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 244 KiB |
|
Before Width: | Height: | Size: 348 KiB |
|
Before Width: | Height: | Size: 901 KiB |
|
Before Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 478 KiB |
|
Before Width: | Height: | Size: 650 KiB |
|
Before Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 547 KiB |
@@ -11,34 +11,35 @@ dependencies {
|
|||||||
compile project(':briar-api')
|
compile project(':briar-api')
|
||||||
compile project(':briar-core')
|
compile project(':briar-core')
|
||||||
compile fileTree(dir: 'libs', include: '*.jar')
|
compile fileTree(dir: 'libs', include: '*.jar')
|
||||||
|
// This shouldn't be necessary; per section 23.4.4 of the Gradle docs:
|
||||||
|
// "file dependencies are included in transitive project dependencies within the same build".
|
||||||
|
compile files('../briar-core/libs/jsocks.jar')
|
||||||
compile "com.android.support:support-v4:$supportVersion"
|
compile "com.android.support:support-v4:$supportVersion"
|
||||||
compile("com.android.support:appcompat-v7:$supportVersion") {
|
compile("com.android.support:appcompat-v7:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
}
|
}
|
||||||
|
compile("com.android.support:preference-v7:$supportVersion") {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
}
|
||||||
compile("com.android.support:preference-v14:$supportVersion") {
|
compile("com.android.support:preference-v14:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
|
exclude module: 'preference-v7'
|
||||||
|
exclude module: 'recyclerview-v7'
|
||||||
}
|
}
|
||||||
compile("com.android.support:design:$supportVersion") {
|
compile("com.android.support:design:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
exclude module: 'recyclerview-v7'
|
exclude module: 'recyclerview-v7'
|
||||||
}
|
}
|
||||||
compile "com.android.support:cardview-v7:$supportVersion"
|
|
||||||
compile 'com.android.support:support-annotations:23.4.0'
|
|
||||||
compile('ch.acra:acra:4.8.5') {
|
compile('ch.acra:acra:4.8.5') {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
exclude module: 'support-annotations'
|
exclude module: 'support-annotations'
|
||||||
}
|
}
|
||||||
compile 'info.guardianproject.panic:panic:0.5'
|
compile 'info.guardianproject.panic:panic:0.5'
|
||||||
compile 'info.guardianproject.trustedintents:trustedintents:0.2'
|
compile 'info.guardianproject.trustedintents:trustedintents:0.2'
|
||||||
compile 'de.hdodenhof:circleimageview:2.1.0'
|
compile 'de.hdodenhof:circleimageview:2.0.0'
|
||||||
compile 'com.google.zxing:core:3.2.1'
|
compile 'com.google.zxing:core:3.2.1'
|
||||||
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
apt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
provided 'javax.annotation:jsr250-api:1.0'
|
provided 'javax.annotation:jsr250-api:1.0'
|
||||||
compile 'com.jpardogo.materialtabstrip:library:1.1.0'
|
|
||||||
compile 'com.github.bumptech.glide:glide:3.7.0'
|
|
||||||
compile 'uk.co.samuelwall:material-tap-target-prompt:1.3.0'
|
|
||||||
|
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'net.jodah:concurrentunit:0.4.2'
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
@@ -46,6 +47,11 @@ dependencies {
|
|||||||
testCompile project(path: ':briar-tests')
|
testCompile project(path: ':briar-tests')
|
||||||
testCompile 'org.robolectric:robolectric:3.0'
|
testCompile 'org.robolectric:robolectric:3.0'
|
||||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||||
|
|
||||||
|
androidTestCompile 'org.robolectric:robolectric:3.0'
|
||||||
|
androidTestCompile 'org.mockito:mockito-core:1.10.19'
|
||||||
|
androidTestApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
androidTestCompile 'junit:junit:4.12'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencyVerification {
|
dependencyVerification {
|
||||||
@@ -53,20 +59,17 @@ dependencyVerification {
|
|||||||
'ch.acra:acra:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
|
'ch.acra:acra:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
|
||||||
'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
|
'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
|
||||||
'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
|
'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
|
||||||
'de.hdodenhof:circleimageview:bcbc588e19e6dcf8c120b1957776bfe229efba5d2fbe5da7156372eeacf65503',
|
'de.hdodenhof:circleimageview:c76d936395b50705a3f98c9220c22d2599aeb9e609f559f6048975cfc1f686b8',
|
||||||
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||||
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
||||||
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
||||||
|
'com.android.support:preference-v7:775101bd07bd052e455761c5c5d9523d7ad59f2f320e3e8cbde241fd6b1d6025',
|
||||||
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
|
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
|
||||||
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
|
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
|
||||||
'com.android.support:support-annotations:e91a88dd0c5e99069b7f09d4a46b5e06f1e9c4c72fc0a8e987e25d86af480f01',
|
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
|
||||||
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
|
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
|
||||||
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
|
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
|
||||||
'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
|
'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
|
||||||
'com.android.support:cardview-v7:4595f1c4a28cfa083b6c0920ad4d49e1c2ca4b8302a955e548f68eb63b74931b',
|
|
||||||
'com.jpardogo.materialtabstrip:library:24d19232b319f8c73e25793432357919a7ed972186f57a3b2c9093ea74ad8311',
|
|
||||||
'com.github.bumptech.glide:glide:76ef123957b5fbaebb05fcbe6606dd58c3bc3fcdadb257f99811d0ac9ea9b88b',
|
|
||||||
'uk.co.samuelwall:material-tap-target-prompt:f67e1caead12a914525b32cbf6da52a96b93ff89573f93cb41102ef3130fb64a',
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,10 +77,6 @@ android {
|
|||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.3"
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
resValue "string", "app_package", "org.briarproject"
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
@@ -101,16 +100,24 @@ android {
|
|||||||
unitTests.returnDefaultValues = true
|
unitTests.returnDefaultValues = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Move the build types to build-types/<type>
|
||||||
|
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
|
||||||
|
// This moves them out of them default location under src/<type>/... which would
|
||||||
|
// conflict with src/ being used by the main source set.
|
||||||
|
// Adding new build types or product flavors should be accompanied
|
||||||
|
// by a similar customization.
|
||||||
|
debug.setRoot('build-types/debug')
|
||||||
|
release.setRoot('build-types/release')
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
shrinkResources false
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
shrinkResources true
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
}
|
}
|
||||||
@@ -122,8 +129,10 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
warning 'MissingTranslation'
|
abortOnError false
|
||||||
warning 'ImpliedQuantity'
|
}
|
||||||
|
dexOptions {
|
||||||
|
incremental true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
-dontobfuscate
|
-dontobfuscate
|
||||||
-verbose
|
-verbose
|
||||||
-useuniqueclassmembernames
|
-useuniqueclassmembernames
|
||||||
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
# For comfortability in case we do obfuscate
|
# For comfortability in case we do obfuscate
|
||||||
# -renamesourcefileattribute SourceFile
|
# -renamesourcefileattribute SourceFile
|
||||||
-keepattributes SourceFile, LineNumberTable, *Annotation*, Signature, InnerClasses, EnclosingMethod
|
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature, InnerClasses, EnclosingMethod
|
||||||
|
|
||||||
-keep public class * extends android.app.Activity
|
-keep public class * extends android.app.Activity
|
||||||
-keep public class * extends android.app.Application
|
-keep public class * extends android.app.Application
|
||||||
-keep public class * extends android.app.Service
|
-keep public class * extends android.app.Service
|
||||||
-keep public class * extends android.content.BroadcastReceiver
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
-keep public class * extends android.content.ContentProvider
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
-keepclasseswithmembers class * { native <methods>; }
|
-keepclasseswithmembers class * { native <methods>; }
|
||||||
-keepclasseswithmembers class * {
|
-keepclasseswithmembers class * {
|
||||||
public <init> (android.content.Context, android.util.AttributeSet);
|
public <init> (android.content.Context, android.util.AttributeSet);
|
||||||
@@ -31,41 +32,31 @@
|
|||||||
-keepclassmembers class * extends android.app.Activity {
|
-keepclassmembers class * extends android.app.Activity {
|
||||||
public void *(android.view.View);
|
public void *(android.view.View);
|
||||||
}
|
}
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@com.google.inject.Inject <init>(...);
|
||||||
|
@com.google.inject.Inject <fields>;
|
||||||
|
}
|
||||||
|
# Just in case Roboguice events are used
|
||||||
|
-keepclassmembers class * {
|
||||||
|
void *(**On*Event);
|
||||||
|
}
|
||||||
|
|
||||||
-keep class org.h2.** { *; }
|
-keep class org.h2.** { *; }
|
||||||
-keep class org.briarproject.** { *; }
|
-keep class org.briarproject.** { *; }
|
||||||
|
-keep class com.google.inject.** { *; }
|
||||||
-keep class javax.inject.** { *; }
|
-keep class javax.inject.** { *; }
|
||||||
|
-keep class javax.annotation.** { *; }
|
||||||
|
-keep class roboguice.** { *; }
|
||||||
-keep class dagger.** { *; }
|
-keep class dagger.** { *; }
|
||||||
-keep class com.google.zxing.Result
|
-keep class com.google.** { *; }
|
||||||
|
|
||||||
-dontwarn org.h2.**
|
-dontwarn org.h2.**
|
||||||
-dontnote org.h2.**
|
-dontnote org.h2.**
|
||||||
-dontwarn net.sf.cglib.**
|
-dontwarn net.sf.cglib.**
|
||||||
-dontwarn org.briarproject.plugins.tcp.**
|
-dontwarn org.briarproject.plugins.tcp.**
|
||||||
-dontnote org.briarproject.crypto.**
|
-dontwarn roboguice.**
|
||||||
-dontnote org.spongycastle.crypto.parsers.ECIESPublicKeyParser
|
|
||||||
-dontwarn net.sourceforge.jsocks.**
|
-dontwarn net.sourceforge.jsocks.**
|
||||||
-dontnote android.support.**
|
-dontnote android.support.**
|
||||||
-dontnote dagger.**
|
-dontnote dagger.**
|
||||||
-dontwarn dagger.**
|
-dontwarn dagger.**
|
||||||
-dontnote com.google.common.**
|
-dontwarn com.google.common.**
|
||||||
-dontwarn com.google.common.**
|
|
||||||
|
|
||||||
# RSS libraries
|
|
||||||
-keep class com.rometools.rome.feed.synd.impl.** { *;}
|
|
||||||
-keep class com.rometools.rome.io.impl.** { *;}
|
|
||||||
-keep class org.jsoup.safety.Whitelist
|
|
||||||
-dontnote com.rometools.rome.**
|
|
||||||
-dontwarn javax.xml.stream.**
|
|
||||||
-dontwarn org.jaxen.**
|
|
||||||
-dontwarn java.nio.**
|
|
||||||
-dontwarn org.codehaus.mojo.animal_sniffer.**
|
|
||||||
-dontwarn org.slf4j.impl.**
|
|
||||||
|
|
||||||
# Emoji
|
|
||||||
-keep class org.thoughtcrime.securesms.**
|
|
||||||
-keep class com.astuetz.PagerSlidingTabStrip$OnTabReselectedListener
|
|
||||||
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
|
|
||||||
**[] $VALUES;
|
|
||||||
public *;
|
|
||||||
}
|
|
||||||
BIN
briar-android/res/drawable-hdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/device_access_accounts.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-hdpi/message_notification_icon.png
Normal file
|
After Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-hdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-ldpi/message_notification_icon.png
Normal file
|
After Width: | Height: | Size: 210 B |
BIN
briar-android/res/drawable-mdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/device_access_accounts.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-mdpi/message_notification_icon.png
Normal file
|
After Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-mdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 1014 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 15 KiB |
16
briar-android/res/drawable-v21/round_button.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
A FAB does not work, because even with fabSize="mini" it will be too big due to shadow drawing
|
||||||
|
on lower API levels
|
||||||
|
-->
|
||||||
|
<ripple
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:color="@color/briar_primary_dark">
|
||||||
|
|
||||||
|
<item>
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<solid android:color="@color/briar_primary"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</ripple>
|
||||||
BIN
briar-android/res/drawable-xhdpi/alerts_and_states_error.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/message_notification_icon.png
Normal file
|
After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 16 KiB |
BIN
briar-android/res/drawable-xhdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_accept.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 17 KiB |
BIN
briar-android/res/drawable-xxhdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 16 KiB |
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.56"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#000000"
|
|
||||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<vector android:alpha="0.54" android:height="24dp"
|
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M15.73,3L8.27,3L3,8.27v7.46L8.27,21h7.46L21,15.73L21,8.27L15.73,3zM12,17.3c-0.72,0 -1.3,-0.58 -1.3,-1.3 0,-0.72 0.58,-1.3 1.3,-1.3 0.72,0 1.3,0.58 1.3,1.3 0,0.72 -0.58,1.3 -1.3,1.3zM13,13h-2L11,7h2v6z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
|
|
||||||
<solid
|
|
||||||
android:color="@android:color/transparent"/>
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:width="2dp"
|
|
||||||
android:color="@color/briar_text_primary"/>
|
|
||||||
|
|
||||||
</shape>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
|
|
||||||
<corners
|
|
||||||
android:radius="@dimen/unread_bubble_size"/>
|
|
||||||
|
|
||||||
<solid
|
|
||||||
android:color="@color/briar_text_primary_inverse"/>
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:color="@color/briar_text_primary"
|
|
||||||
android:width="1dp"/>
|
|
||||||
|
|
||||||
</shape>
|
|
||||||
|
|
||||||
@@ -1,9 +1,4 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector android:height="24dp" android:viewportHeight="48.0"
|
||||||
android:width="24dp"
|
android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:height="24dp"
|
<path android:fillColor="#FF000000" android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
|
||||||
android:viewportHeight="48.0"
|
|
||||||
android:viewportWidth="48.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#06b9ff"
|
|
||||||
android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector android:height="24dp" android:viewportHeight="48.0"
|
||||||
android:width="24dp"
|
android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
android:height="24dp"
|
<path android:fillColor="#FF000000" android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
|
||||||
android:viewportHeight="48.0"
|
|
||||||
android:viewportWidth="48.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#06b9ff"
|
|
||||||
android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM19,15.59L17.59,17 14,13.41 10.41,17 9,15.59 12.59,12 9,8.41 10.41,7 14,10.59 17.59,7 19,8.41 15.41,12 19,15.59z"/>
|
|
||||||
</vector>
|
|
||||||