Skip to content

Commit

Permalink
Make enabling analytics and setting region id globally (#36)
Browse files Browse the repository at this point in the history
* Make region id as a global variable to simplify the usage

* Use PXLClient.autoAnalyticsEnabled as a global variable to enable auto-analytics on PXLPhotoRecyclerView.kt and PXLPhotoRecyclerViewInGrid.kt

* Use PXLClient.autoAnalyticsEnabled as a global variable to enable auto-analytics on PXLPhotoProductView.kt

* Remove a deprecated method

* clean up views

* Add a test for no auto-analytics

* Add @deprecated annotation to notify SDK users that apis because of its duplicated functionality.
Update document

* Update document

* Update document

* Fix typo

* Feature/add circle ci (#37)

* add circleci

* Fix lint errors

* Add circleci

* Update circleci

* change version of circleci

* update circle to fix erros

* update circle to fix errors

* update circle to fix errors2

* update circle to fix errors

* update circle to fix errors

* update circle to fix errors

* Add pixleekey.properties in circleci

* Remove saving results data

* Display project id in circleci console to show the full url of the test result

* Split circleci messages

* Force to fail a test

* Restore tests

* Fix hmac test

* Fix Unit tests to avoid using android.util.Base64 because All Android related packages are not available in unit tests.

* Fix and add unit tests

* Fix and add unit tests

* Fix circleci

* Split test

* Split test

* Fix unit tests

* Remove unnecessary tests

* force to fail an unit test

* Restore tests

Co-authored-by: sungjun <[email protected]>

Co-authored-by: sungjun <[email protected]>
  • Loading branch information
SungjunApp and sungjun authored Feb 8, 2021
1 parent 5353c91 commit ae1fbeb
Show file tree
Hide file tree
Showing 52 changed files with 831 additions and 601 deletions.
89 changes: 89 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
version: 2.1
workflows:
testing:
jobs:
- unit:
filters:
tags:
only: /.*/
branches:
only: /.*/
- ui:
filters:
tags:
only: /.*/
branches:
only: /.*/

jobs:
unit:
docker:
- image: circleci/android:api-28-node
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
steps:
- checkout
- copy-pixlee-credentials
- unit-tests
ui:
docker:
- image: circleci/android:api-28-node
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
steps:
- checkout
- copy-pixlee-credentials
- ui-tests
commands:
copy-pixlee-credentials:
steps:
- run:
name: Store Pixlee crecentials into pixleekey.properties
command: |
echo "$PIXLEE_PROPERTIES" | base64 --decode > pixleekey.properties
ls -al
unit-tests:
steps:
- restore_cache:
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Download Dependencies
command: ./gradlew androidDependencies
- save_cache:
paths:
- ~/.gradle
key: jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
- run:
name: Run Tests
command: ./gradlew lint test
- store_artifacts: # for display in Artifacts: https://circleci.com/docs/2.0/artifacts/
path: app/build/reports
destination: reports
- store_test_results: # for display in Test Summary: https://circleci.com/docs/2.0/collect-test-data/
path: app/build/test-results
ui-tests:
steps:
- run:
name: Build debug APK and release APK
command: |
./gradlew :app:assembleDebug
./gradlew :app:assembleDebugAndroidTest
- run:
name: Store Google Service Account
command: echo $GCLOUD_SERVICE_KEY > ${HOME}/gcloud-service-key.json
- run:
name: Authorize gcloud and set config defaults
command: |
sudo gcloud auth activate-service-account --key-file=${HOME}/gcloud-service-key.json
sudo gcloud --quiet config set project pixlee-sdk
- run:
name: Test with Firebase Test Lab
command: >
sudo gcloud firebase test android run \
--type instrumentation \
--app app/build/outputs/apk/debug/app-debug.apk \
--test app/build/outputs/apk/androidTest/debug/app-debug-androidTest.apk \
--device model=Nexus6,version=21,locale=en,orientation=portrait \
--results-bucket cloud-test-pixlee-sdk
27 changes: 23 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,18 @@ android {
}

testOptions {
unitTests.returnDefaultValues = true
// unitTests.returnDefaultValues = true
testOptions {
unitTests.all {
// All the usual Gradle options.
testLogging {
events "passed", "skipped", "failed", "standardOut", "standardError"
outputs.upToDateWhen {false}
showStandardStreams = true
}
}
}
}

}

repositories {
Expand All @@ -52,12 +61,22 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testImplementation 'junit:junit:4.12'
testImplementation 'junit:junit:4.13'

/**
* testing
*/
androidTestImplementation 'androidx.test.ext:junit-ktx:' + rootProject.extJUnitVersion

testImplementation 'org.json:json:20200518'
testImplementation "com.fasterxml.jackson.core:jackson-databind:2.10.3"
//testImplementation "com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8"
testImplementation "com.squareup.okhttp3:mockwebserver:$okhttp3"

androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
androidTestImplementation 'androidx.test.ext:junit:' + rootProject.extJUnitVersion
androidTestImplementation "androidx.test.ext:junit-ktx:" + rootProject.extJUnitVersion
androidTestImplementation "com.fasterxml.jackson.core:jackson-databind:2.10.3"
androidTestImplementation 'androidx.test.espresso:espresso-contrib:' + rootProject.espressoVersion
androidTestImplementation "com.jakewharton.espresso:okhttp3-idling-resource:$jakeWhartonOkhttpOdlingResource"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.pixlee.pixleesdk;
package com.pixlee.pixleeandroidsdk;

import android.content.Context;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

import com.pixlee.pixleesdk.client.PXLAlbum;
import com.pixlee.pixleesdk.client.PXLBaseAlbum;
Expand All @@ -18,7 +17,6 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
Expand All @@ -27,35 +25,26 @@
import java.util.Date;
import java.util.Random;

import static org.junit.Assert.assertEquals;

/***
* PXLAlbum tests
*/
@RunWith(AndroidJUnit4.class)
public class AlbumTests {
private final static String TestAlbumId = "5984962";
private final static String TestApiKey = "ccWQFNExi4gQjyNYpOEf";// "zk4wWCOaHAo4Hi8HsE";
private final static String TestAlbumId = BuildConfig.PIXLEE_ALBUM_ID;
private final static String TestApiKey = BuildConfig.PIXLEE_API_KEY;
private PXLAlbum testAlbum;
private Random random;
private int requestCount;

@Before
public void setup() {
Context c = InstrumentationRegistry.getTargetContext();
PXLClient.initialize(TestApiKey);
PXLClient.Companion.initialize(TestApiKey, null);

testAlbum = new PXLAlbum(TestAlbumId, PXLClient.getInstance(c));
testAlbum = new PXLAlbum(TestAlbumId, PXLClient.Companion.getInstance(c));
this.random = new Random();
requestCount = 0;
}

@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.pixlee.pixleesdk.test", appContext.getPackageName());
}

@Test
public void testFilters() throws Exception {
Expand Down Expand Up @@ -88,7 +77,7 @@ public void onError(String error) {
public void testPhotoLoad() throws Exception {
requestCount++;
// update api key and photo id to match
String album_photo_id = "187177895";
String album_photo_id = "381257461";
testAlbum.getPhotoWithId(album_photo_id, new PXLBaseAlbum.RequestHandlers<PXLPhoto>() {
@Override
public void onComplete(PXLPhoto photo) {
Expand Down Expand Up @@ -142,6 +131,7 @@ private ArrayList<PXLAlbumFilterOptions> getTestFilterOptions() throws IllegalAc
for (int i = 0; i < fields.length; i++) {
PXLAlbumFilterOptions fo = new PXLAlbumFilterOptions();
Object val = this.getTestVal(fields[i]);

if (val != null) {
fields[i].set(fo, val);
} else {
Expand All @@ -153,6 +143,10 @@ private ArrayList<PXLAlbumFilterOptions> getTestFilterOptions() throws IllegalAc
}

private Object getTestVal(Field field) {
if("filterByRadius".equals(field.getName())){
return "21.3069,-157.8583,20";
}

Class<?> type = field.getType();
if (type.equals(Boolean.TYPE) || type.equals(Boolean.class)) {
return random.nextBoolean();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import androidx.test.filters.LargeTest
import com.pixlee.pixleeandroidsdk.tool.MyViewAction
import com.pixlee.pixleeandroidsdk.tool.OkHttpIdlingResourceRule
import com.pixlee.pixleeandroidsdk.tool.ScrollToBottomAction
import com.pixlee.pixleesdk.client.PXLClient
import com.pixlee.pixleesdk.data.api.AnalyticsEvents
import com.pixlee.pixleesdk.network.observer.AnalyticsObserver
import com.pixlee.pixleesdk.ui.viewholder.PXLPhotoViewHolder
import org.hamcrest.Matcher
import org.hamcrest.StringDescription
Expand All @@ -32,7 +34,6 @@ import org.junit.runner.RunWith
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
@LargeTest
class AnalyticsFragmentTest {
/**
Expand All @@ -46,37 +47,53 @@ class AnalyticsFragmentTest {
@get:Rule
var rule = OkHttpIdlingResourceRule()

@Test
fun testListHavingAnalyticsOff() {
// open widget
PXLClient.autoAnalyticsEnabled = false
onView(withId(R.id.btKtxAlbumList)).perform(waitUntil(isDisplayed())).perform(ViewActions.click())
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsObserver.noEventsMessage))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsObserver.noEventsMessage))))
onView(withId(R.id.tvDebugText)).check(matches(withText(StringContains.containsString(AnalyticsObserver.noEventsMessage))))

// open lightbox by clicking an item in list
onView(withId(R.id.pxlPhotoRecyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition<PXLPhotoViewHolder>(0, MyViewAction.clickChildViewWithId(R.id.vListRoot)))
onView(withId(R.id.tvDebugTextViewer)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsObserver.noEventsMessage))))
}

@Test
fun testList() {
val buttonId = R.id.tvDebugText

// open widget
PXLClient.autoAnalyticsEnabled = true
onView(withId(R.id.btKtxAlbumList)).perform(waitUntil(isDisplayed())).perform(ViewActions.click())
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
onView(withId(buttonId)).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
onView(withId(R.id.tvDebugText)).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))

// scroll down to load more photos
onView(withId(R.id.pxlPhotoRecyclerView)).perform(ScrollToBottomAction())
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.loadMore))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.loadMore))))
}

@Test
fun testGrid() {
val buttonId = R.id.tvDebugText

// open grid widget
PXLClient.autoAnalyticsEnabled = true
onView(withId(R.id.btKtxAlbumGrid)).perform(waitUntil(isDisplayed())).perform(ViewActions.click())
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
}

@Test
fun testProductDetail() {
val buttonId = R.id.tvDebugText
// open widget
PXLClient.autoAnalyticsEnabled = true
onView(withId(R.id.btKtxAlbumList)).perform(waitUntil(isDisplayed())).perform(ViewActions.click())
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(buttonId)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))
onView(withId(R.id.pxlPhotoRecyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition<PXLPhotoViewHolder>(0, MyViewAction.clickChildViewWithId(R.id.vListRoot)))
//Thread.sleep(1000)
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedWidget))))
onView(withId(R.id.tvDebugText)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.widgetVisible))))

// open lightbox by clicking an item in list
onView(withId(R.id.pxlPhotoRecyclerView)).perform(RecyclerViewActions.actionOnItemAtPosition<PXLPhotoViewHolder>(0, MyViewAction.clickChildViewWithId(R.id.vListRoot)))
onView(withId(R.id.tvDebugTextViewer)).perform(waitUntil(isDisplayed())).check(matches(withText(StringContains.containsString(AnalyticsEvents.openedLightbox))))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
Expand Down
36 changes: 0 additions & 36 deletions app/src/androidTest/java/com/pixlee/pixleeandroidsdk/HMACTest.java

This file was deleted.

33 changes: 33 additions & 0 deletions app/src/androidTest/java/com/pixlee/pixleeandroidsdk/HMACTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.pixlee.pixleeandroidsdk

import android.util.Log
import androidx.test.runner.AndroidJUnit4
import com.fasterxml.jackson.databind.ObjectMapper
import com.pixlee.pixleesdk.network.HMAC
import org.json.JSONException
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import java.security.InvalidKeyException
import java.security.NoSuchAlgorithmException

/**
* Created by sungjun on 2/1/21.
*/
class HMACTest {
@Test
@Throws(JSONException::class, InvalidKeyException::class, NoSuchAlgorithmException::class)
fun `test-HMAC-SHA1`() {
val text: String = ObjectMapper().createObjectNode().apply{
this.put("album_id", 12345)
this.put("title", "Testing Photo Upload")
this.put("approved", true)
this.put("email", "[email protected]")
this.put("username", "Submitter Person")
this.put("photo_uri", "https://example.com/test.jpg")
}.toString().replace("\\/", "/")
val test = HMAC.computeHmac(text, "ABCDEFG")
val targetResult = "epBvDlHbQho/rNDdQVJowWMtGsg="
Assert.assertEquals(targetResult, test)
}
}
Loading

0 comments on commit ae1fbeb

Please sign in to comment.