Skip to content

Commit a0a0020

Browse files
committed
add test for class utils
1 parent 4bf0862 commit a0a0020

3 files changed

Lines changed: 220 additions & 2 deletions

File tree

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ dependencies {
143143
testImplementation("androidx.test:core:$androidXTestVersion")
144144
testImplementation("junit:junit:$junitVersion")
145145
testImplementation("org.robolectric:robolectric:4.16")
146+
testImplementation("org.mockito:mockito-core:5.8.0")
146147

147148
androidTestImplementation("androidx.test:core:$androidXTestVersion")
148149
androidTestImplementation("junit:junit:$junitVersion")

app/src/main/java/protect/card_locker/importexport/CatimaImporter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public boolean isDuplicate(Context context, final LoyaltyCard existing, final Lo
163163
}
164164
for (ImageLocationType imageLocationType : ImageLocationType.values()) {
165165
String nameExists = Utils.getCardImageFileName(existing.id, imageLocationType);
166-
String nameChecksum = nameExists.replaceFirst("card_\\d+_", "card_" + card.id + "_");
166+
String nameChecksum = Utils.getCardImageFileName(card.id, imageLocationType);
167167

168168
boolean exists = existingImages.contains(nameExists);
169169
if (exists != imageChecksums.containsKey(nameChecksum)) {

app/src/test/java/protect/card_locker/UtilsTest.java

Lines changed: 218 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
package protect.card_locker;
22

3+
import static org.junit.Assert.assertEquals;
34
import static org.junit.Assert.assertFalse;
5+
import static org.junit.Assert.assertNotNull;
6+
import static org.junit.Assert.assertTrue;
7+
import static org.mockito.ArgumentMatchers.any;
8+
import static org.mockito.Mockito.atLeastOnce;
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.verify;
11+
import static org.mockito.Mockito.when;
412

13+
import android.content.Context;
514
import android.content.res.TypedArray;
15+
import android.graphics.Bitmap;
616
import android.graphics.Color;
17+
import android.widget.ImageView;
718

819
import androidx.test.core.app.ActivityScenario;
920

1021
import org.junit.Test;
1122
import org.junit.runner.RunWith;
1223
import org.robolectric.RobolectricTestRunner;
1324

25+
import java.io.ByteArrayInputStream;
26+
import java.io.File;
27+
import java.io.FileInputStream;
28+
import java.io.InputStream;
29+
import java.util.Random;
1430

1531
@RunWith(RobolectricTestRunner.class)
1632
public class UtilsTest {
@@ -24,11 +40,212 @@ public void allDefaultCardColoursHaveWhiteForegroundTest() {
2440
TypedArray colors = activity.getApplicationContext().getResources().obtainTypedArray(R.array.letter_tile_colors);
2541

2642
for (int i = 0; i < colors.length(); i++) {
27-
// Grab white as fallback so that if the retrieval somehow fails the test is guaranteed to fail because a white background will have black foreground
2843
int color = colors.getColor(i, Color.WHITE);
2944
assertFalse(Utils.needsDarkForeground(color));
3045
}
3146
});
3247
}
3348
}
49+
50+
/**
51+
* Test checksum method with a fake (small) input stream
52+
*/
53+
@Test
54+
public void testChecksum_withFakeInputStream() throws Exception {
55+
byte[] fakeContent = "test content".getBytes();
56+
InputStream fakeStream = new ByteArrayInputStream(fakeContent);
57+
58+
String checksum = Utils.checksum(fakeStream);
59+
60+
assertNotNull(checksum);
61+
assertTrue(checksum.matches("[0-9a-f]+"));
62+
}
63+
64+
/**
65+
* Test checksum method with large random content (1 MB)
66+
*/
67+
@Test
68+
public void testChecksum_withLargeContent() throws Exception {
69+
byte[] largeContent = new byte[1024 * 1024];
70+
new Random().nextBytes(largeContent);
71+
InputStream largeStream = new ByteArrayInputStream(largeContent);
72+
73+
String checksum = Utils.checksum(largeStream);
74+
75+
assertNotNull(checksum);
76+
assertTrue(checksum.matches("[0-9a-f]+"));
77+
}
78+
79+
/**
80+
* Test checksum method using a mocked FileInputStream
81+
*/
82+
@Test
83+
public void testChecksum_withMockedFileInputStream() throws Exception {
84+
FileInputStream mockStream = mock(FileInputStream.class);
85+
when(mockStream.read(any(byte[].class))).thenReturn(-1);
86+
87+
String checksum = Utils.checksum(mockStream);
88+
89+
assertNotNull(checksum);
90+
verify(mockStream, atLeastOnce()).read(any(byte[].class));
91+
}
92+
93+
/**
94+
* Test getUnixTime method returns reasonable timestamp
95+
*/
96+
@Test
97+
public void testGetUnixTime() {
98+
long unixTime = Utils.getUnixTime();
99+
100+
// Unix time should be positive
101+
assertTrue("Unix time should be positive", unixTime > 0);
102+
103+
// Should be reasonable (after year 2020 and before year 2030)
104+
long year2020 = 1577836800L; // Jan 1, 2020
105+
long year2030 = 1893456000L; // Jan 1, 2030
106+
107+
assertTrue("Unix time should be after 2020", unixTime > year2020);
108+
assertTrue("Unix time should be before 2030", unixTime < year2030);
109+
}
110+
111+
/**
112+
* Test createTempFile method with mocked context
113+
*/
114+
@Test
115+
public void testCreateTempFile() {
116+
// Create a mock context
117+
Context mockContext = mock(Context.class);
118+
File mockCacheDir = new File("/mock/cache");
119+
120+
when(mockContext.getCacheDir()).thenReturn(mockCacheDir);
121+
122+
// Test file creation
123+
String fileName = "test_file.txt";
124+
File result = Utils.createTempFile(mockContext, fileName);
125+
126+
assertNotNull("Should return a File object", result);
127+
assertTrue("File path should contain cache directory", result.getPath().contains("cache"));
128+
assertTrue("File path should contain filename", result.getPath().contains(fileName));
129+
assertEquals("Should create correct file path", "\\mock\\cache\\test_file.txt", result.getPath());
130+
}
131+
132+
/**
133+
* Test getComplementaryColor method
134+
*/
135+
@Test
136+
public void testGetComplementaryColor() {
137+
// Test with pure red
138+
int red = Color.rgb(255, 0, 0);
139+
int complementRed = Utils.getComplementaryColor(red);
140+
assertEquals("Complement of red should be cyan", Color.rgb(0, 255, 255), complementRed);
141+
142+
// Test with white
143+
int white = Color.WHITE;
144+
int complementWhite = Utils.getComplementaryColor(white);
145+
assertEquals("Complement of white should be black", Color.BLACK, complementWhite);
146+
147+
// Test with black
148+
int black = Color.BLACK;
149+
int complementBlack = Utils.getComplementaryColor(black);
150+
assertEquals("Complement of black should be white", Color.WHITE, complementBlack);
151+
152+
// Test with gray (should remain the same)
153+
int gray = Color.rgb(128, 128, 128);
154+
int complementGray = Utils.getComplementaryColor(gray);
155+
assertEquals("Complement of gray should be gray", Color.rgb(127, 127, 127), complementGray);
156+
}
157+
158+
/**
159+
* Test getRecommendedScaleTypeForThumbnailImage method
160+
*/
161+
@Test
162+
public void testGetRecommendedScaleTypeForThumbnailImage() {
163+
// Test with null bitmap
164+
ImageView.ScaleType result = Utils.getRecommendedScaleTypeForThumbnailImage(null);
165+
assertEquals("Should return FIT_CENTER for null bitmap", ImageView.ScaleType.FIT_CENTER, result);
166+
167+
// Create mock bitmaps with different aspect ratios
168+
Bitmap mockBitmapSquare = mock(Bitmap.class);
169+
when(mockBitmapSquare.getWidth()).thenReturn(100);
170+
when(mockBitmapSquare.getHeight()).thenReturn(100);
171+
172+
result = Utils.getRecommendedScaleTypeForThumbnailImage(mockBitmapSquare);
173+
assertEquals("Should return FIT_CENTER for square image", ImageView.ScaleType.FIT_CENTER, result);
174+
175+
// Test with ideal card ratio (around 1.58)
176+
Bitmap mockBitmapCard = mock(Bitmap.class);
177+
when(mockBitmapCard.getWidth()).thenReturn(158);
178+
when(mockBitmapCard.getHeight()).thenReturn(100);
179+
180+
result = Utils.getRecommendedScaleTypeForThumbnailImage(mockBitmapCard);
181+
assertEquals("Should return CENTER_CROP for card-like aspect ratio", ImageView.ScaleType.CENTER_CROP, result);
182+
183+
// Test with very wide image
184+
Bitmap mockBitmapWide = mock(Bitmap.class);
185+
when(mockBitmapWide.getWidth()).thenReturn(300);
186+
when(mockBitmapWide.getHeight()).thenReturn(100);
187+
188+
result = Utils.getRecommendedScaleTypeForThumbnailImage(mockBitmapWide);
189+
assertEquals("Should return FIT_CENTER for very wide image", ImageView.ScaleType.FIT_CENTER, result);
190+
}
191+
192+
/**
193+
* Test basicMDToHTML method with various markdown patterns
194+
*/
195+
@Test
196+
public void testBasicMDToHTML() {
197+
// Test heading conversion
198+
String input = "# Main Title\n## Subtitle";
199+
String expected = "<h1>Main Title</h1>\n<h2>Subtitle</h2>";
200+
assertEquals("Should convert headings correctly", expected, Utils.basicMDToHTML(input));
201+
202+
// Test link conversion
203+
input = "Visit [GitHub](https://github.com)";
204+
expected = "Visit <a href=\"https://github.com\">GitHub</a>";
205+
assertEquals("Should convert links correctly", expected, Utils.basicMDToHTML(input));
206+
207+
// Test bold text conversion
208+
input = "This is **bold** text";
209+
expected = "This is <b>bold</b> text";
210+
assertEquals("Should convert bold text correctly", expected, Utils.basicMDToHTML(input));
211+
212+
// Test list item conversion
213+
input = "- First item\n- Second item";
214+
expected = "<ul><li>&nbsp;First item</li></ul>\n<ul><li>&nbsp;Second item</li></ul>";
215+
// The method should merge consecutive list items
216+
String actual = Utils.basicMDToHTML(input);
217+
assertTrue("Should contain list items", actual.contains("<li>&nbsp;First item</li>"));
218+
assertTrue("Should contain list items", actual.contains("<li>&nbsp;Second item</li>"));
219+
}
220+
221+
/**
222+
* Test linkify method for automatic link detection
223+
*/
224+
@Test
225+
public void testLinkify() {
226+
// Test email linkification
227+
String input = "Contact us at support@example.com";
228+
String result = Utils.linkify(input);
229+
assertTrue("Should linkify email addresses",
230+
result.contains("<a href=\"mailto:support@example.com\">support@example.com</a>"));
231+
232+
// Test URL linkification
233+
input = "Visit https://www.example.com for more info";
234+
result = Utils.linkify(input);
235+
assertTrue("Should linkify URLs",
236+
result.contains("<a href=\"https://www.example.com\">https://www.example.com</a>"));
237+
238+
// Test mixed content
239+
input = "Email: test@domain.org and website: http://example.net";
240+
result = Utils.linkify(input);
241+
assertTrue("Should linkify email in mixed content",
242+
result.contains("<a href=\"mailto:test@domain.org\">test@domain.org</a>"));
243+
assertTrue("Should linkify URL in mixed content",
244+
result.contains("<a href=\"http://example.net\">http://example.net</a>"));
245+
246+
// Test no links
247+
input = "Just plain text with no links";
248+
result = Utils.linkify(input);
249+
assertEquals("Should not modify text without links", input, result);
250+
}
34251
}

0 commit comments

Comments
 (0)