Skip to content

Commit 89263c3

Browse files
miltonialsjamescr
authored andcommitted
new test confirming TrackContentProvider bugs
1 parent c488fa3 commit 89263c3

1 file changed

Lines changed: 200 additions & 0 deletions

File tree

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
package net.osmtracker.db;
2+
3+
import android.content.ContentResolver;
4+
import android.content.ContentUris;
5+
import android.content.ContentValues;
6+
import android.content.Context;
7+
import android.database.Cursor;
8+
import android.net.Uri;
9+
10+
import androidx.test.core.app.ApplicationProvider;
11+
12+
import org.junit.Before;
13+
import org.junit.Test;
14+
import org.junit.runner.RunWith;
15+
import org.robolectric.RobolectricTestRunner;
16+
import org.robolectric.annotation.Config;
17+
18+
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assert.assertNotNull;
20+
import static org.junit.Assert.assertThrows;
21+
import static org.junit.Assert.assertTrue;
22+
23+
/**
24+
* Bug-confirming tests for {@link TrackContentProvider}.
25+
*
26+
* <p>Every test in this class documents a <strong>known bug</strong> by asserting the current
27+
* broken behaviour. Each test passes <em>because</em> the bug exists — the tests are expected
28+
* to <strong>fail</strong> once the corresponding bug is fixed.
29+
*
30+
* <p>When a bug is fixed:
31+
* <ol>
32+
* <li>Remove the {@literal @}Ignore annotation from the matching test in
33+
* {@link TrackContentProviderTest} (the intended-behaviour companion).</li>
34+
* <li>Delete (or permanently skip) the test in this class — it no longer represents
35+
* correct expected behaviour.</li>
36+
* <li>Run {@code ./gradlew testDebugUnitTest} — the formerly-{@literal @}Ignored test in
37+
* {@link TrackContentProviderTest} must now pass.</li>
38+
* </ol>
39+
*
40+
* <p>See {@code docs/BUGS_TrackContentProvider.md} for the full description of each bug.
41+
*/
42+
@RunWith(RobolectricTestRunner.class)
43+
@Config(sdk = 25)
44+
public class TrackContentProviderTestBugs {
45+
46+
private ContentResolver resolver;
47+
48+
@Before
49+
public void setUp() {
50+
Context context = ApplicationProvider.getApplicationContext();
51+
resolver = context.getContentResolver();
52+
}
53+
54+
// ── Shared helpers ────────────────────────────────────────────────────────
55+
56+
private long insertTrack() {
57+
ContentValues values = new ContentValues();
58+
values.put(TrackContentProvider.Schema.COL_START_DATE, System.currentTimeMillis());
59+
Uri uri = resolver.insert(TrackContentProvider.CONTENT_URI_TRACK, values);
60+
assertNotNull(uri);
61+
return ContentUris.parseId(uri);
62+
}
63+
64+
private Uri insertNote(long trackId, String uuid) {
65+
ContentValues values = new ContentValues();
66+
values.put(TrackContentProvider.Schema.COL_TRACK_ID, trackId);
67+
values.put(TrackContentProvider.Schema.COL_LATITUDE, 40.7);
68+
values.put(TrackContentProvider.Schema.COL_LONGITUDE, -74.0);
69+
values.put(TrackContentProvider.Schema.COL_TIMESTAMP, System.currentTimeMillis());
70+
values.put(TrackContentProvider.Schema.COL_NAME, "Note " + uuid);
71+
values.put(TrackContentProvider.Schema.COL_UUID, uuid);
72+
return resolver.insert(TrackContentProvider.notesUri(trackId), values);
73+
}
74+
75+
// ── Bug B11: delete(TRACK_ID) does not delete notes ──────────────────────
76+
77+
/**
78+
* Bug B11 — When deleting a track by ID, the associated notes are NOT deleted.
79+
*
80+
* <p>The {@code delete()} method in {@code TrackContentProvider} handles
81+
* {@code URI_CODE_TRACK_ID} by deleting waypoints and trackpoints, but it does
82+
* not delete notes from the note table. This leaves orphaned note rows in the database.
83+
*
84+
* <p>This test passes because the bug exists (notes remain after track deletion).
85+
* When Bug B11 is fixed, this test will fail and should be deleted.
86+
* Remove {@literal @}Ignore from
87+
* {@code TrackContentProviderTest#delete_trackById_alsoRemovesNotes}.
88+
*
89+
* @see TrackContentProviderTest#delete_trackById_alsoRemovesNotes
90+
*/
91+
@Test
92+
public void bug_B11_delete_trackById_doesNotDeleteNotes() {
93+
long trackId = insertTrack();
94+
insertNote(trackId, "orphan-note-1");
95+
insertNote(trackId, "orphan-note-2");
96+
97+
// Delete the track
98+
Uri trackUri = ContentUris.withAppendedId(TrackContentProvider.CONTENT_URI_TRACK, trackId);
99+
resolver.delete(trackUri, null, null);
100+
101+
// Verify notes are still present (the bug)
102+
Cursor c = resolver.query(TrackContentProvider.notesUri(trackId),
103+
null, null, null, null);
104+
try {
105+
assertNotNull(c);
106+
assertTrue("Bug B11: notes should remain after track deletion (they are orphaned)",
107+
c.getCount() > 0);
108+
assertEquals("Bug B11: both notes should be orphaned", 2, c.getCount());
109+
} finally {
110+
if (c != null) c.close();
111+
}
112+
}
113+
114+
// ── Bug B12: getType() throws for 9 valid URI codes ──────────────────────
115+
116+
/**
117+
* Bug B12 — {@code getType()} throws {@code IllegalArgumentException} for
118+
* {@code URI_CODE_TRACK_ID}. Only 4 of 13 valid URI codes are handled.
119+
*
120+
* <p>Each test below confirms that getType() throws for a valid URI.
121+
* When Bug B12 is fixed, these tests will fail and should be deleted.
122+
* Remove {@literal @}Ignore from the corresponding tests in
123+
* {@link TrackContentProviderTest}.
124+
*/
125+
@Test
126+
public void bug_B12_getType_throwsForTrackId() {
127+
long trackId = insertTrack();
128+
Uri uri = ContentUris.withAppendedId(TrackContentProvider.CONTENT_URI_TRACK, trackId);
129+
assertThrows("Bug B12: getType should not throw for track/#",
130+
IllegalArgumentException.class,
131+
() -> resolver.getType(uri));
132+
}
133+
134+
@Test
135+
public void bug_B12_getType_throwsForTrackActive() {
136+
assertThrows("Bug B12: getType should not throw for track/active",
137+
IllegalArgumentException.class,
138+
() -> resolver.getType(TrackContentProvider.CONTENT_URI_TRACK_ACTIVE));
139+
}
140+
141+
@Test
142+
public void bug_B12_getType_throwsForWaypointId() {
143+
Uri uri = TrackContentProvider.waypointUri(1);
144+
assertThrows("Bug B12: getType should not throw for waypoint/#",
145+
IllegalArgumentException.class,
146+
() -> resolver.getType(uri));
147+
}
148+
149+
@Test
150+
public void bug_B12_getType_throwsForWaypointUuid() {
151+
Uri uri = Uri.withAppendedPath(
152+
TrackContentProvider.CONTENT_URI_WAYPOINT_UUID, "test-uuid");
153+
assertThrows("Bug B12: getType should not throw for waypoint/uuid/*",
154+
IllegalArgumentException.class,
155+
() -> resolver.getType(uri));
156+
}
157+
158+
@Test
159+
public void bug_B12_getType_throwsForTrackpointId() {
160+
Uri uri = TrackContentProvider.trackpointUri(1);
161+
assertThrows("Bug B12: getType should not throw for trackpoint/#",
162+
IllegalArgumentException.class,
163+
() -> resolver.getType(uri));
164+
}
165+
166+
@Test
167+
public void bug_B12_getType_throwsForNoteId() {
168+
Uri uri = TrackContentProvider.noteUri(1);
169+
assertThrows("Bug B12: getType should not throw for note/#",
170+
IllegalArgumentException.class,
171+
() -> resolver.getType(uri));
172+
}
173+
174+
@Test
175+
public void bug_B12_getType_throwsForNoteUuid() {
176+
Uri uri = Uri.withAppendedPath(
177+
TrackContentProvider.CONTENT_URI_NOTE_UUID, "test-uuid");
178+
assertThrows("Bug B12: getType should not throw for note/uuid/*",
179+
IllegalArgumentException.class,
180+
() -> resolver.getType(uri));
181+
}
182+
183+
@Test
184+
public void bug_B12_getType_throwsForTrackStart() {
185+
long trackId = insertTrack();
186+
Uri uri = TrackContentProvider.trackStartUri(trackId);
187+
assertThrows("Bug B12: getType should not throw for track/#/start",
188+
IllegalArgumentException.class,
189+
() -> resolver.getType(uri));
190+
}
191+
192+
@Test
193+
public void bug_B12_getType_throwsForTrackEnd() {
194+
long trackId = insertTrack();
195+
Uri uri = TrackContentProvider.trackEndUri(trackId);
196+
assertThrows("Bug B12: getType should not throw for track/#/end",
197+
IllegalArgumentException.class,
198+
() -> resolver.getType(uri));
199+
}
200+
}

0 commit comments

Comments
 (0)