Day 23

Testing time-specific notifications

Worked on testing notifications for Prompt today. The main idea with this application is to deliver writing prompts in time for a specific window, in order to create a daily writing habit. Notifications working well and occurring at the appropriate times is a pretty important part of that. Maybe the most important part. So I need to get this right.

I started by writing out the basic idea of what I want to test:

# Create some test users.
# Create relevant times.
# Set up user details.
# Check that each user has some prompts.
# Check that the prompts are unsent.
# Move time to be before next sending window (5am today).
# Send notifications. Check that none sent.
# Move time to next sending window (6am).
# Send notifications. Check that one prompt is sent.
# Move time to some time after that (9am).
# Send notifications. Check that no prompts are sent.
# Move time to next sending window (6am following day).
# Send notifications. Check that one prompt is sent.

For simplicity’s sake, I’m assuming that everyone has their prompt delivery time set to 6am. This is a long integration test that will do many things in succession and verify that nothing breaks.

To start, I create the user records and key times that are important:

# Create some test users.
@user_one = users(:signed_in_guest)
@user_two = users(:signed_out_guest)
# Create relevant times.
today =
=, today.month,, 6).utc
tomorrow =
=, tomorrow.month,, 6).utc

Nothing too exciting here. Using fixtures for the user records and creating some times at 6am both today and tomorrow.

# Set user details.
@user_one.update_attributes(send_next_prompt_at: todays_prompt_time)
@user_two.update_attributes(send_next_prompt_at: todays_prompt_time)
# Check that the guest has some prompts.
assert @user_one.prompts.count >= 3
assert @user_two.prompts.count >= 3
# Check that the prompts are unsent.
assert_equal @user_one.prompts.count, @user_one.prompts.unsent.count
assert_equal @user_two.prompts.count, @user_two.prompts.unsent.count

I’m updating the user records with the next time that a prompt will be sent for this user. I started off with the idea of tracking the last time that a prompt was sent, but this seems like it will work better because a user might update the time they want their prompts to be sent and it will be difficult derive that from the previous sent time in that case. This also makes it very easy to query the users who are ready to go.

I’m also checking that there are some test prompts set up to work with, in case the fixture data is changed some time in the future.

The most interesting part is checking the code at a certain time. I’m using Rails’ built-in travel_to function for this:

# Set time to be before next sending window (5am today).
travel_to todays_prompt_time - 1.hour do
# Send notifications. Check that none sent.
assert_no_difference "Prompt.sent.count" do

This sets the time to 5am on the current day, which is too early for our prompts to be sent. I’m planning on sending no earlier than 10 minutes before. So we “move” the time and check to see that no prompts are sent when the sending function is called.

This is as far as I got today, but once I get this part of the test passing, I’ll follow a similar pattern with the other times of interest and that should flesh out the time-sensitive sending portion of the app.

Excited to get this knocked out and get version one out soon. Not much time left before I need to ship!