import { AppCacheService } from './app-cache.service';
import { FeedVersionService } from './feed-version.service';

describe('FeedVersionService', () => {
  const cache = { get: jest.fn(), set: jest.fn(), incr: jest.fn() } as unknown as AppCacheService;
  const service = new FeedVersionService(cache);

  beforeEach(() => jest.clearAllMocks());

  it('returns existing positive global and user versions', async () => {
    (cache.get as jest.Mock).mockResolvedValueOnce(7).mockResolvedValueOnce(3);
    await expect(service.getGlobalVersion()).resolves.toBe(7);
    await expect(service.getUserVersion('u1')).resolves.toBe(3);
    expect(cache.set).not.toHaveBeenCalled();
  });

  it.each([null, 0, -1, '1'])('initializes invalid global version %p', async (stored) => {
    (cache.get as jest.Mock).mockResolvedValue(stored);
    await expect(service.getGlobalVersion()).resolves.toBe(1);
    expect(cache.set).toHaveBeenCalledWith('feed:global:version', 1);
  });

  it('initializes an absent user version and bumps both scopes', async () => {
    (cache.get as jest.Mock).mockResolvedValue(null);
    (cache.incr as jest.Mock).mockResolvedValueOnce(4).mockResolvedValueOnce(9);
    await expect(service.getUserVersion('u2')).resolves.toBe(1);
    expect(cache.set).toHaveBeenCalledWith('feed:user:u2:version', 1);
    await expect(service.bumpGlobalVersion()).resolves.toBe(4);
    await expect(service.bumpUserVersion('u2')).resolves.toBe(9);
    expect(cache.incr).toHaveBeenNthCalledWith(1, 'feed:global:version');
    expect(cache.incr).toHaveBeenNthCalledWith(2, 'feed:user:u2:version');
  });
});
