import { useUserPref } from '@/composables/userPref.composable';

describe('userPref Composable', () => {
  beforeEach(() => {
    vi.resetAllMocks();
    vi.resetModules();
    vi.stubGlobal('localStorage', {
      getItem: vi.fn(),
      setItem: vi.fn(),
    });
  });
  describe('getUserPref', () => {
    const { getUserPref } = useUserPref();
    it('should return undefined if no localStorage available', () => {
      (localStorage.getItem as any).mockReturnValueOnce(null);
      expect(getUserPref('key')).toEqual(undefined);
    });
    it('should return undefined if localStorage has no value for searched path', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": false, "path2": true}',
      );
      expect(getUserPref('key', 'path3')).toEqual(undefined);
    });
    it('should return undefined if localStorage is not correctly formated', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value"}, "path2": true',
      );
      expect(getUserPref('key', 'path1')).toEqual(undefined);
    });
    it('should return undefined if localStorage does not have key for path', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value"}, "path2": true}',
      );
      expect(getUserPref('keyNotExisting', 'path1')).toEqual(undefined);
    });
    it('should return the value if localStorage has key for path', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value"}, "path2": true}',
      );
      expect(getUserPref('key', 'path1')).toEqual('value');
    });
    it('should return the value if localStorage has key for global', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {}, "path2": true, "global": {"key": "value"}}',
      );
      expect(getUserPref('key')).toEqual('value');
    });
  });

  describe('saveUserPref', () => {
    const { saveUserPref } = useUserPref();
    it('should create a new entry in localStorage if there is no pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(null);
      saveUserPref('key', 'value', 'path');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"path":{"key":"value"}}',
      );
    });
    it('should create a new entry in localStorage in global if there is no pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(null);
      saveUserPref('key', 'value');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"global":{"key":"value"}}',
      );
    });
    it('should add a new entry in localStorage if there is no pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value"}, "path2": true}',
      );
      saveUserPref('key', 'value', 'path3');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"path1":{"key":"value"},"path2":true,"path3":{"key":"value"}}',
      );
    });
    it('should add a new entry in localStorage in global if there is no pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value"}, "path2": true}',
      );
      saveUserPref('key', 'value');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"path1":{"key":"value"},"path2":true,"global":{"key":"value"}}',
      );
    });
    it('should edit a entry in localStorage if there is pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value","key2":"value3"}, "path2": true}',
      );
      saveUserPref('key', 'value2', 'path1');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"path1":{"key":"value2","key2":"value3"},"path2":true}',
      );
    });
    it('should edit a global entry in localStorage if there is pref saved', () => {
      (localStorage.getItem as any).mockReturnValueOnce(
        '{"path1": {"key": "value","key2":"value3"}, "path2": true,"global":{"key":"value"}}',
      );
      saveUserPref('key', 'value2');
      expect(localStorage.setItem).toHaveBeenCalled();
      expect(localStorage.setItem).toHaveBeenCalledWith(
        'userPref',
        '{"path1":{"key":"value","key2":"value3"},"path2":true,"global":{"key":"value2"}}',
      );
    });
  });
});
