Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2c0cca9
HW-53053. Split ui modules
azakrevska-epam May 27, 2019
9ba8f51
HW-53053. Added jacoco settings
azakrevska-epam May 27, 2019
7949065
Merge with package changes + multi module build
fmattos-hw May 28, 2019
7218015
HW-53053. Changed publishing
azakrevska-epam May 28, 2019
ad0970e
Remove comments and unnecessary plugin usages
fmattos-hw May 28, 2019
6a9b6b2
move sonar config
fmattos-hw May 28, 2019
89d922e
HW-53053. Moved font, styles, colors to common module
azakrevska-epam May 29, 2019
d4867c7
Merge remote-tracking branch 'origin/task/HW-53053-ui-splitted-module…
azakrevska-epam May 29, 2019
ec3b001
Merge branch 'development' into task/HW-53053-ui-splitted-modules
azakrevska-epam May 29, 2019
57121d4
HW-53053. Fixed moved style
azakrevska-epam May 30, 2019
16bce86
HW-53053. Updated lint (added exceptions for overdraw)
azakrevska-epam May 30, 2019
ab7b653
HW-52584 draft receipt list
May 30, 2019
f5fbb62
HW-52584 draft test
May 30, 2019
b9f84d9
added test and test templates for receipts
May 30, 2019
551a0af
removed junit4 runner
May 30, 2019
b1f98dc
removed currency symbol
May 31, 2019
2bf85b8
ui changes from requirements and adding ellipsis support
May 31, 2019
4fa2e7b
added new icon set
Jun 3, 2019
500f702
added Event live data pattern
Jun 3, 2019
b7fcec4
improve ellipsis
Jun 3, 2019
bf880f2
Merge branch 'development' into task/HW-53053-ui-splitted-modules
azakrevska-epam Jun 4, 2019
7c6b5d9
HW-53053. Updated library versions
azakrevska-epam Jun 4, 2019
e574593
add receipt transaction description
fmattos-hw Jun 4, 2019
eb22f26
initial receipt type integration
Jun 4, 2019
a230034
Merge remote-tracking branch 'remotes/origin/task/HW-53053-ui-splitte…
Jun 4, 2019
fbf2721
renamed test
Jun 4, 2019
bf8599c
updated diff and order of fields
Jun 4, 2019
92b910f
added test
Jun 5, 2019
d8c0bb3
Merge remote-tracking branch 'remotes/origin/development' into task/H…
Jun 5, 2019
a53786b
Moving equals implementation in core
Jun 5, 2019
a22bd77
fixed integration test
Jun 6, 2019
905bb6a
fixed ellipsis approach
Jun 6, 2019
9fbc21d
added constants
Jun 6, 2019
cd017a3
added transfer method status query in list transfer method ui module
Jun 6, 2019
77ea3ca
addressed comments
Jun 7, 2019
ab3cb53
removed locale changes
Jun 7, 2019
6ba7e59
ui updates
Jun 7, 2019
e65b897
added sync ui fix
Jun 7, 2019
192a1ae
divider improvement
Jun 7, 2019
c2b3374
added timezone default
Jun 7, 2019
c23374d
fixed multi-timezone support
Jun 10, 2019
f3f8578
added license
Jun 10, 2019
41384fe
comment
Jun 10, 2019
fa4f4d3
added fix for HW-53592
Jun 11, 2019
2c58aa6
added header check
Jun 11, 2019
ef55dda
added header check first element
Jun 11, 2019
eee9009
HW-53401. Added ui tests for list receipts (#34)
azakrevska-epam Jun 11, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ subprojects {
constraintlayoutVersion = '1.1.3'
legacySupportV4Version = '1.0.0'
recycleViewVersion = '1.0.0'
lifecycleExtensionsVersion = '2.0.0'
pagingRuntimeVersion = '2.1.0'
//Testing
extJunitVerson = '1.1.1'
testRunnerVersion = '1.2.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* The MIT License (MIT)
* Copyright (c) 2019 Hyperwallet Systems Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.hyperwallet.android.common.util;

import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
* Common HW-SDK UI Date Utility class, that will assist on safe presentation of date whatever the mobile device setting
* is set Locale, Timezone and etc... that dictates how that dates are being presented
*
* Moreover all date string to {@link Date} object conversion is automatically converted from
* GMT date string from API to locale Date set by the phone
*/
public final class DateUtils {

private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";
private static final String DATE_TIME_FORMAT_MILLISECONDS = "yyyy-MM-dd'T'HH:mm:ss.SSS";
private static final TimeZone API_TIMEZONE = TimeZone.getTimeZone("GMT");

private DateUtils() {
}

/**
* Creates a string date format: <code>yyyy-MM-dd</code>
*
* @param date Date object
* @return string date in <code>yyyy-MM-dd</code> format
*/
public static String toDateFormat(@NonNull final Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.getDefault());
dateFormat.setTimeZone(TimeZone.getDefault());
return dateFormat.format(date);
}

/**
* Creates a string date in specified format
*
* @param date Date object
* @param format specify desired format of date
* @return formatted date string based on format specified
*/
public static String toDateFormat(@NonNull final Date date, @NonNull final String format) {
SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.getDefault());
dateFormat.setTimeZone(TimeZone.getDefault());
return dateFormat.format(date);
}

/**
* Creates a string date format
*
* @param date Date object
* @return formatted string in <code>yyyy-MM-dd'T'HH:mm:ss</code> format
*/
public static String toDateTimeFormat(@NonNull final Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT, Locale.getDefault());
dateFormat.setTimeZone(TimeZone.getDefault());
return dateFormat.format(date);
}

/**
* Creates a string date format
*
* @param date Date object
* @return formatted string in <code>yyyy-MM-dd'T'HH:mm:ss.SSS</code> format
*/
public static String toDateTimeMillisFormat(@NonNull final Date date) {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT_MILLISECONDS, Locale.getDefault());
dateFormat.setTimeZone(TimeZone.getDefault());
return dateFormat.format(date);
}

/**
* Creates a Date object from string date using API Timezone
*
* @param dateString String date from API with GMT timezone
* @return date Date object converted to local timezone
* @throws IllegalArgumentException when string is un-parsable
*/
public static Date fromDateTimeString(@NonNull final String dateString) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_TIME_FORMAT, Locale.getDefault());
dateFormat.setTimeZone(API_TIMEZONE);
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new IllegalArgumentException("An exception occurred when attempting to parse " +
"the date " + dateString, e);
}
}

@VisibleForTesting
static Date fromDateTimeString(@NonNull final String dateString, @NonNull final String format) {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.getDefault());
dateFormat.setTimeZone(API_TIMEZONE);
return dateFormat.parse(dateString);
} catch (ParseException e) {
throw new IllegalArgumentException("An exception occurred when attempting to parse " +
"the date " + dateString, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.hyperwallet.android.ui.view;
package com.hyperwallet.android.common.view;

import android.content.Context;
import android.graphics.Canvas;
Expand All @@ -26,12 +26,12 @@
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.hyperwallet.android.hyperwallet_ui.R;
import com.hyperwallet.android.common.R;

public class HorizontalDividerItemDecorator extends RecyclerView.ItemDecoration {

private final Drawable mHorizontalItemDivider;
private final int mDefaultPadding;
protected final Drawable mHorizontalItemDivider;
protected final int mDefaultPadding;

public HorizontalDividerItemDecorator(@NonNull final Context context, final boolean withHeaderDivider) {
mHorizontalItemDivider = context.getResources().getDrawable(R.drawable.horizontal_divider, null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* The MIT License (MIT)
* Copyright (c) 2019 Hyperwallet Systems Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package com.hyperwallet.android.common.viewmodel;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Class that represents {@link androidx.lifecycle.LiveData} event with content
*/
public class Event<T> {

private final T content;
private boolean mIsContentConsumed;

public Event(@NonNull final T t) {
content = t;
}

/**
* @return content of this event, will also mark {@link Event#mIsContentConsumed} to <code>true</code>
* that will also mean that {@link Event#getContentIfNotConsumed()} will also return <code>true</code>
*/
@NonNull
public T getContent() {
mIsContentConsumed = true;
return content;
}

/**
* @return <code>true</code> if content assigned to event is already referenced
* from {@link Event#getContent()}; <code>false</code> otherwise.
*/
public boolean isContentConsumed() {
return mIsContentConsumed;
}

/**
* Retrieve assigned content based on if and only if content has not been referenced from {@link Event#getContent()}
*
* @return content if content is not yet consumed; otherwise null
*/
@Nullable
public T getContentIfNotConsumed() {
if (!mIsContentConsumed) {
mIsContentConsumed = true;
return content;
}
return null;
}
}
2 changes: 1 addition & 1 deletion common/src/main/res/drawable/circle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<item>
<shape android:shape="oval">
<solid android:color="@color/fontIconBackground" />
<size android:width="48dp" android:height="48dp"/>
<size android:width="@dimen/circle_icon" android:height="@dimen/circle_icon"/>
</shape>
</item>
</selector>
Expand Down
8 changes: 3 additions & 5 deletions common/src/main/res/drawable/circle_white.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
<item>

<shape android:shape="oval">


<stroke android:color="#737373" android:width="3dp"/>
<size android:width="48dp" android:height="48dp"/>

<stroke android:color="@color/iconCircleWhite"
android:width="@dimen/circle_white_density"/>
<size android:width="@dimen/circle_icon" android:height="@dimen/circle_icon"/>
</shape>
</item>

Expand Down
Binary file modified common/src/main/res/font/icomoon.ttf
Binary file not shown.
1 change: 1 addition & 0 deletions common/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@

<!-- Icon decoration color -->
<color name="fontIconBackground">#E5F7FA</color>
<color name="iconCircleWhite">#737373</color>
</resources>

2 changes: 2 additions & 0 deletions common/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,6 @@
<dimen name="menu_icon_default_margin">4dp</dimen>
<dimen name="text_input_hint_text_padding">6dp</dimen>
<dimen name="widget_left_margin_offset">32dp</dimen>
<dimen name="circle_icon">48dp</dimen>
<dimen name="circle_white_density">3dp</dimen>
</resources>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.hyperwallet.android.common.util;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.Before;
import org.junit.Test;

import java.util.Date;
import java.util.TimeZone;

public class DateUtilsTest {

@Before
public void setTestLocalTimezone() {
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
}

@Test
public void testToDateFormat_returnsExpectedStringFormat() {
String dateString = "2019-05-27";
Date dateTarget = DateUtils.fromDateTimeString("2019-05-27T15:57:49");

// test
String targetDate = DateUtils.toDateFormat(dateTarget);
assertThat(targetDate, is(notNullValue()));
assertThat(targetDate, is(dateString));
}

@Test
public void testToDateFormat_returnsExpectedStringFormatFromParameter() {
String dateString = "November 2019";
Date dateTarget = DateUtils.fromDateTimeString("2019-11-27T15:57:49");

// test
String targetDate = DateUtils.toDateFormat(dateTarget, "MMMM yyyy");
assertThat(targetDate, is(notNullValue()));
assertThat(targetDate, is(dateString));
}

@Test
public void testToDateTimeFormat_returnsExpectedStringFormat() {
String localTime = "2019-11-27T07:57:00";
Date dateTarget = DateUtils.fromDateTimeString("2019-11-27T15:57:00");

// test
String targetDate = DateUtils.toDateTimeFormat(dateTarget);
assertThat(targetDate, is(notNullValue()));
assertThat(targetDate, is(localTime));
}

@Test
public void testToDateTimeMillisFormat_returnsExpectedStringFormat() {
String localTime = "2019-11-27T07:57:00.000";
Date dateTarget = DateUtils.fromDateTimeString("2019-11-27T15:57:00.000", "yyyy-MM-dd'T'HH:mm:ss.SSS");

// test
String targetDate = DateUtils.toDateTimeMillisFormat(dateTarget);
assertThat(targetDate, is(notNullValue()));
assertThat(targetDate, is(localTime));
}
}
16 changes: 16 additions & 0 deletions receipt/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@ apply from: "$rootProject.projectDir/android-library.gradle"

dependencies {
api project(":common")

implementation "com.google.android.material:material:$androidMaterialVersion"
implementation "androidx.constraintlayout:constraintlayout:$constraintlayoutVersion"
implementation "androidx.legacy:legacy-support-v4:$legacySupportV4Version"
implementation "androidx.recyclerview:recyclerview:$recycleViewVersion"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleExtensionsVersion"
implementation "androidx.paging:paging-runtime:$pagingRuntimeVersion"

testImplementation "org.robolectric:robolectric:$robolectricVersion"

androidTestImplementation "androidx.test:rules:$testRulesVersion"
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
androidTestImplementation "com.squareup.okhttp3:mockwebserver:$mockServerVersion"
androidTestImplementation "com.squareup.leakcanary:leakcanary-android-instrumentation:$leakcanaryVersion"
androidTestImplementation "com.squareup.leakcanary:leakcanary-support-fragment:$leakcanaryVersion"
}

def aarFile = file("$buildDir/outputs/aar/receipt-$version" + ".aar")
Expand Down
9 changes: 9 additions & 0 deletions receipt/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hyperwallet.android.receipt.test">

<application android:name="com.hyperwallet.android.HyperwalletInstrumentedTestApplication">

</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.hyperwallet.android;


import android.app.Application;

import com.squareup.leakcanary.InstrumentationLeakDetector;
import com.squareup.leakcanary.LeakCanary;

public class HyperwalletInstrumentedTestApplication extends Application {

@Override
public void onCreate() {

super.onCreate();
if (LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
return;
}
installLeakCanary();
}


protected void installLeakCanary() {

InstrumentationLeakDetector.instrumentationRefWatcher(this)
.buildAndInstall();

}

}
Loading