Skip to content

Support If-Modified-Since header for feed caching#326

Merged
ai merged 13 commits intohplush:mainfrom
immitsu:issue-324
Jan 9, 2026
Merged

Support If-Modified-Since header for feed caching#326
ai merged 13 commits intohplush:mainfrom
immitsu:issue-324

Conversation

@immitsu
Copy link
Copy Markdown
Contributor

@immitsu immitsu commented Jan 3, 2026

Resolves #324

@immitsu
Copy link
Copy Markdown
Contributor Author

immitsu commented Jan 3, 2026

If everything is generally ok, we can add core/test/feed.test.ts here to restore test coverage

UPD: No longer relevant

Comment thread core/test/loader/rss.test.ts Outdated
Comment thread core/feed.ts Outdated
Comment thread proxy/index.ts
Comment thread proxy/index.ts Outdated
Comment thread core/loader/rss.ts
Comment thread core/test/loader/rss.test.ts Outdated
})
})

test('handles 304 not modified response', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am trying to avoid “unit” test ideology in the project. My dream is to test behavior, not implementation.

What do you think of test scenarios like:

  1. Mock response and return Last-Modified header
  2. Run refresh()
  3. Mock second response and expect to have If-Modified-Since and response with 304
  4. Run refresh() again

With this scenario we will check that the whole system works, and we will not need to change test on any implementation changes (like on changing Loader API and Last-Modified storage).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reworked

Comment thread core/loader/atom.ts Outdated
})
})

test('handles conditional request when server returns 304', async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like new tests.

The only note: what do you think if we will have the same 1 test here as we have for Atom/JSONFeed (or maybe I am missing something)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We added a test case named "handles conditional request when server returns 304" for each of RSS, Atom, and JSON.

For RSS, "sends If-Modified-Since header when refreshedAt is provided" was also added.

Do you mean that it should be removed because it partially duplicates the previous one, i.e., to keep just a single test?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between:

  • sends If-Modified-Since header when refreshedAt is provided
  • handles conditional request when server returns 304

in RSS tests?

Copy link
Copy Markdown
Contributor Author

@immitsu immitsu Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first test verifies the correctness of request formation – whether the correct If-Modified-Since header is sent when refreshedAt is provided.

The second test verifies the correctness of response handling – whether the system properly reacts to a 304 status by returning an empty posts list.

Formally, they serve different purposes. This is an argument for keeping both tests for each feed type.

However, in the current implementation, the second test fully duplicates the first one – it adds a mock 304 response and checks the entire flow. In both tests we call loaders.rss.getPosts, and without refreshedAt both would fail.

But the code might change in the future, so keeping both tests could be useful

Copy link
Copy Markdown
Contributor

@ai ai Jan 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recent Danny Preussler talk convinced me that unit tests approach is not very helpful. The price of test maintenance is more that it gives in return because we need constantly update tests.

Separated tests for like this is that “unit test” approach. For instance, if we will change loader API, we will need to update test.

The new idea is that tests should test “user side feature” and not implementation (”If it walks like a duck and quacks like a duck, it's a duck”).

So I suggest removing one test and instead have only one test (technically 3, one for Atom, one for RSS, one for JSON Feed) that check both thing.

It will be nice to have in refresh.test.ts another test, which will be like e2e test where we:

  1. Create feed
  2. Mock request with 200 and time header and test that it was without header
  3. Refresh posts
  4. Mock request with 304 and check that time from step 2 was sent
  5. Refresh post again

This test will test that app saves feed’s last updated time somewhere and use it again (but do not care about implementation).

Of course, we can do this test in separated PR (or I can generate it with LLM if you don't like tests :D). But I want to share with you this idea of more e2e-ish approach with testing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it now, thanks – you mentioned that before. Let me add it in the PR

Copy link
Copy Markdown
Contributor Author

@immitsu immitsu Jan 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a new test to refresh.test.ts and removed an unit test from rss.test.ts

@ai
Copy link
Copy Markdown
Contributor

ai commented Jan 5, 2026

Nice, I like new feature a lot =^_^= Thanks for your awesome work.

@immitsu
Copy link
Copy Markdown
Contributor Author

immitsu commented Jan 6, 2026

Nice, I like new feature a lot =^_^= Thanks for your awesome work.

Thank you for this project (and many others), the detailed review, and the valuable feedback

Comment thread core/loader/common.ts Outdated
@ai
Copy link
Copy Markdown
Contributor

ai commented Jan 7, 2026

Looks awesome. I will apply it today or tomorrow.

If you have Twitter/Mastadon/BlueSky give it, I am going to write about this PR in my accounts.

@ai ai merged commit 81973ce into hplush:main Jan 9, 2026
10 checks passed
@ai
Copy link
Copy Markdown
Contributor

ai commented Jan 9, 2026

I cleaned test a lot, it maybe be interesting for you (mostly small tuning) 40e103c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use If-Modified-Since to speed up feed update

2 participants