1
00:00:04,220 --> 00:00:06,340
G'day everyone, welcome back.

2
00:00:06,340 --> 00:00:13,800
In the last video, we saw our AppDialog class displaying a dialog,
when we try to delete a Task record.

3
00:00:13,800 --> 00:00:20,000
The next step is to get MainActivityFragment to handle the
situation correctly.

4
00:00:20,000 --> 00:00:28,380
Correctly here means, not performing the deletion until the
user has confirmed that they really do want to delete the task.

5
00:00:28,380 --> 00:00:35,900
We achieve that by moving the deleteTask call
into the onPositiveDialogResult function.

6
00:00:35,900 --> 00:00:39,500
So we'll cut these two lines from here,

7
00:00:39,500 --> 00:00:43,480
and paste them down here.

8
00:00:43,480 --> 00:00:47,840
We've got an error because the task id isn't available.

9
00:00:47,840 --> 00:01:03,860
We can fix that by retrieving the id from the args bundle.

10
00:01:03,860 --> 00:01:08,140
We should also make sure that we're
responding to the correct dialog.

11
00:01:08,140 --> 00:01:14,200
We're only showing one dialog at the moment,
but we don't want to go deleting tasks by mistake.

12
00:01:14,200 --> 00:01:25,020
So let's wrap this in an if block.

13
00:01:25,020 --> 00:01:29,820
I haven't included a check that the task id key exists in the bundle.

14
00:01:29,820 --> 00:01:33,820
You could do, and throw an exception if it doesn't exist.

15
00:01:33,820 --> 00:01:44,840
Let's check the documentation for the getLong
function, using ctrl Q, or ctrl J on a Mac.

16
00:01:44,840 --> 00:01:49,560
getLong returns 0 if the key isn't present in the bundle.

17
00:01:49,560 --> 00:01:52,720
If that happens, it's a programming error.

18
00:01:52,720 --> 00:02:00,880
It can't happen once the app's released,
because Sqlite doesn't create integer primary key values of 0.

19
00:02:00,880 --> 00:02:06,520
We should always have a non zero ID, unless
the programmer has done something wrong.

20
00:02:06,520 --> 00:02:20,320
Rather than throwing an exceptionm we can use an assertion.

21
00:02:20,320 --> 00:02:25,840
This is different to just testing
the task id and throwing an exception.

22
00:02:25,840 --> 00:02:31,860
BuildConfig.DEBUG is a system-wide
constant that the compiler can use.

23
00:02:31,860 --> 00:02:37,460
When you produce the release version of
the app, BuildConfi.debug will be false,

24
00:02:37,460 --> 00:02:41,100
and this code won't be compiled into the final app.

25
00:02:41,100 --> 00:02:46,640
It will only be present while we're developing,
and won't appear in the released app.

26
00:02:46,640 --> 00:02:51,700
This is one time where it's acceptable
to put all the code on one line, by the way.

27
00:02:51,700 --> 00:03:04,040
To see it working, I'll comment out the line that adds
a task id to the bundle in the onDelete click function,

28
00:03:04,040 --> 00:03:09,780
then run the app again.

29
00:03:09,780 --> 00:03:14,260
I'll tap the delete button.

30
00:03:14,260 --> 00:03:18,280
When I tap the dialog's delete button to confirm the deletion,

31
00:03:18,280 --> 00:03:31,660
we get an exception in the logcat:

32
00:03:31,660 --> 00:03:33,880
task id is zero.

33
00:03:33,880 --> 00:03:40,720
There's a subtle difference between this
MainActivityFragment class, and the AppDialog class.

34
00:03:40,720 --> 00:03:47,040
MainActivityFragment is part of this TaskTimer
app and won't be used anywhere else.

35
00:03:47,040 --> 00:03:52,720
AppDialog, on the other hand, has been designed
to be a general-purpose dialog class,

36
00:03:52,720 --> 00:03:54,800
that we can use in other apps.

37
00:03:54,800 --> 00:03:58,220
We could still be using other apps in ten years time.

38
00:03:58,220 --> 00:04:01,880
Other members of our team could be including it in their apps,

39
00:04:01,880 --> 00:04:07,540
so that's why we've taken a different approach
to invalid arguments in the two classes.

40
00:04:07,540 --> 00:04:15,720
Our assert error in MainActivityFragment is there to warn
us that we've forgotten to store the task  in the bundle.

41
00:04:15,720 --> 00:04:21,459
The assert error code will be removed when
the release version of the app's compiled.

42
00:04:21,459 --> 00:04:27,180
The exceptions in AppDialog are intended to
warn other programmers who use the class.

43
00:04:27,180 --> 00:04:29,820
That may be us, but it may not be.

44
00:04:29,820 --> 00:04:35,420
The AppDialog exceptions aren't removed when
the code is compiled as a release version.

45
00:04:35,420 --> 00:04:42,320
We might want to compile it, and include it in a
library that's imported into other projects, for example.

46
00:04:42,320 --> 00:04:46,400
So we want the checks to remain in the compiled release version.

47
00:04:46,400 --> 00:04:53,740
Okay, I'll put back the code to store the id in the bundle,

48
00:04:53,740 --> 00:05:00,520
and let's see if it works.

49
00:05:00,520 --> 00:05:05,920
Run the app again, and I'm going to do
the non-destructive tests first.

50
00:05:05,920 --> 00:05:12,620
You don't want to spend time watching me type in the
task records, so I'll try to keep deletions to a minimum.

51
00:05:12,620 --> 00:05:16,180
I suggest you don't take that approach in your testing.

52
00:05:16,180 --> 00:05:18,660
It makes sense when doing a quick check,

53
00:05:18,660 --> 00:05:24,480
but always performing operations in the same sequence,
can result in you missing bugs.

54
00:05:24,480 --> 00:05:31,460
To make up an example, if your edit code creates a
global object that's also used when you delete,

55
00:05:31,460 --> 00:05:39,160
and you always edit before deleting. you might fail
to spot that the delete code fails to create the object.

56
00:05:39,160 --> 00:05:40,200
Okay.

57
00:05:40,200 --> 00:05:46,300
I'll tap on the delete button to get the confirmation dialogue.

58
00:05:46,300 --> 00:05:51,880
First, I'll use the cancel button.

59
00:05:51,880 --> 00:05:55,540
Remember, that's not the same as
cancelling the dialogue.

60
00:05:55,540 --> 00:06:01,460
We give the button the caption cancel,
but it's really the negative dialog button.

61
00:06:01,460 --> 00:06:04,380
That's good. The record isn't deleted.

62
00:06:04,380 --> 00:06:09,740
There are two ways to cancel dialogue,
and both do exactly the same thing.

63
00:06:09,740 --> 00:06:17,820
To test that, I'll delete again, and tap
the screen outside the dialogue.

64
00:06:17,820 --> 00:06:22,380
The dialogue closes, and the task hasn't been deleted.

65
00:06:22,380 --> 00:06:25,400
The same thing should happen with the back button.

66
00:06:25,400 --> 00:06:33,720
So get the dialogue back, and press the back button.

67
00:06:33,720 --> 00:06:36,320
That's working fine as well.

68
00:06:36,320 --> 00:06:38,560
Now to test deletion.

69
00:06:38,560 --> 00:06:51,980
I'll clear the logcat, then delete a task and
confirm the deletion.

70
00:06:51,980 --> 00:06:57,740
A bit more happens here, because we're
causing the database notification system to kick in.

71
00:06:57,740 --> 00:07:04,340
But we can see the onPositiveDialogResult
function, then the record being deleted,

72
00:07:04,340 --> 00:07:13,620
and we can see it's gone from the emulator screen.

73
00:07:13,620 --> 00:07:29,100
Mixed in with all the database logging, we can see the
dialog's onDismiss and onDetach functions in the log.

74
00:07:29,100 --> 00:07:35,460
Notice that the deletion and subsequent
re-query, are happening on a different thread.

75
00:07:35,460 --> 00:07:39,240
Alright, our AppDialog class is looking good.

76
00:07:39,240 --> 00:07:41,420
There's a few things we haven't tested.

77
00:07:41,420 --> 00:07:45,860
Does it work when we provide a different
caption for the negative button?

78
00:07:45,860 --> 00:07:51,620
Does it work when we don't provide any button
captions, and rely on the defaults for both?

79
00:07:51,620 --> 00:07:54,500
Does everything work okay in landscape.

80
00:07:54,500 --> 00:07:57,840
I'm not going to go through those tests on
the video,

81
00:07:57,840 --> 00:08:03,180
but you should certainly test all combinations
of input, to any classes you create.

82
00:08:03,180 --> 00:08:07,720
I'll leave you to perform those tests, and stop this video here.

83
00:08:07,720 --> 00:08:12,420
In the next video, we'll have a quick look at some strange behavior.

84
00:08:12,420 --> 00:08:15,160
See you in the next one.

