All files / client/src/utils sessionStorage.ts

88.7% Statements 55/62
79.16% Branches 19/24
100% Functions 11/11
88.33% Lines 53/60

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154                        520x                           520x 27x   520x 21x     520x 27x             520x 12x     520x 9x           520x   520x 1622x       1622x 1622x 338x     338x     1284x     520x       520x 1622x       1622x 1622x 1622x                       520x 1622x 1589x 1583x     520x 1622x       1622x 1622x 1583x 1583x     39x     520x   520x 1622x       1622x 1622x 1589x     1589x     33x     520x   520x 371x       371x 371x 362x     9x 9x             9x    
import { z } from "zod";
import {
  appUpdateReloadedBuildTimeKey,
  browserStorageEventPrefix,
  kompassiLoginStateKey,
} from "shared/constants/browserStorage";
import { AgeGroup, Language, Tag } from "shared/types/models/programItem";
import { StringToJsonSchema } from "client/utils/zodUtils";
import { StartingTimeOption } from "client/views/all-program-items/programListUtils";
 
// A const object instead of an enum because enum members can't hold the
// computed event-specific prefix
export const SessionStorageValue = {
  ALL_PROGRAM_ITEMS_SEARCH_TERM: `${browserStorageEventPrefix}-allProgramItemsSearchTerm`,
  ALL_PROGRAM_ITEMS_TAG: `${browserStorageEventPrefix}-allProgramItemsTag`,
  ALL_PROGRAM_ITEMS_SELECTED_VIEW: `${browserStorageEventPrefix}-allProgramItemsSelectedView`,
  ALL_PROGRAM_ITEMS_STARTING_TIME: `${browserStorageEventPrefix}-allProgramItemsStartingTime`,
  ALL_PROGRAM_ITEMS_HIDE_FULL: `${browserStorageEventPrefix}-allProgramItemsHideFull`,
  MY_PROGRAM_ITEMS_SHOW_ALL_PROGRAM_ITEMS: `${browserStorageEventPrefix}-myProgramItemsShowAllProgramItems`,
  APP_UPDATE_RELOADED_BUILD_TIME: appUpdateReloadedBuildTimeKey,
  KOMPASSI_LOGIN_STATE: kompassiLoginStateKey,
} as const;
 
// The OAuth state of the login this tab started, compared against the value
// Kompassi echoes back to prove the callback answers our own request. Stored
// as a plain string, so there is no shape to validate on the way out
export const getKompassiLoginState = (): string =>
  sessionStorage.getItem(SessionStorageValue.KOMPASSI_LOGIN_STATE) ?? "";
 
export const saveKompassiLoginState = (state: string): void => {
  sessionStorage.setItem(SessionStorageValue.KOMPASSI_LOGIN_STATE, state);
};
 
export const clearKompassiLoginState = (): void => {
  sessionStorage.removeItem(SessionStorageValue.KOMPASSI_LOGIN_STATE);
};
 
// The server build an automatic update reload was already attempted for.
// Session-scoped so a reload that fails to deliver the new build (e.g. stale
// HTML served again) is not retried in a loop in the same tab. Stored as a
// plain string, so there is no shape to validate on the way out
export const getAppUpdateReloadedBuildTime = (): string =>
  sessionStorage.getItem(SessionStorageValue.APP_UPDATE_RELOADED_BUILD_TIME) ??
  "";
 
export const saveAppUpdateReloadedBuildTime = (buildTime: string): void => {
  sessionStorage.setItem(
    SessionStorageValue.APP_UPDATE_RELOADED_BUILD_TIME,
    buildTime,
  );
};
 
const SavedSearchTermSchema = z.string();
 
export const getSavedSearchTerm = (): string => {
  const serializedValue = sessionStorage.getItem(
    SessionStorageValue.ALL_PROGRAM_ITEMS_SEARCH_TERM,
  );
 
  const result = SavedSearchTermSchema.safeParse(serializedValue);
  if (!result.success) {
    sessionStorage.removeItem(
      SessionStorageValue.ALL_PROGRAM_ITEMS_SEARCH_TERM,
    );
    return "";
  }
 
  return result.data;
};
 
const SavedTagsSchema = z.array(
  z.enum(Tag).or(z.enum(Language)).or(z.enum(AgeGroup)),
);
 
export const getSavedTags = (): (Tag | Language | AgeGroup)[] => {
  const serializedValue = sessionStorage.getItem(
    SessionStorageValue.ALL_PROGRAM_ITEMS_TAG,
  );
 
  const parseJsonResult = StringToJsonSchema.safeParse(serializedValue);
  Eif (!parseJsonResult.success) {
    return [];
  }
 
  const result = SavedTagsSchema.safeParse(parseJsonResult.data);
  if (!result.success) {
    sessionStorage.removeItem(SessionStorageValue.ALL_PROGRAM_ITEMS_TAG);
    return [];
  }
 
  return result.data;
};
 
const SavedHideFullSchema = z.preprocess((val) => {
  if (val === "true") return true;
  if (val === "false") return false;
  return;
}, z.boolean().nullable());
 
export const getSavedHideFull = (): boolean => {
  const serializedValue = sessionStorage.getItem(
    SessionStorageValue.ALL_PROGRAM_ITEMS_HIDE_FULL,
  );
 
  const result = SavedHideFullSchema.safeParse(serializedValue);
  if (!result.success) {
    sessionStorage.removeItem(SessionStorageValue.ALL_PROGRAM_ITEMS_HIDE_FULL);
    return false;
  }
 
  return result.data ?? false;
};
 
const SavedStartingTimeSchema = z.enum(StartingTimeOption);
 
export const getSavedStartingTime = (): StartingTimeOption => {
  const serializedValue = sessionStorage.getItem(
    SessionStorageValue.ALL_PROGRAM_ITEMS_STARTING_TIME,
  );
 
  const result = SavedStartingTimeSchema.safeParse(serializedValue);
  if (!result.success) {
    sessionStorage.removeItem(
      SessionStorageValue.ALL_PROGRAM_ITEMS_STARTING_TIME,
    );
    return StartingTimeOption.UPCOMING;
  }
 
  return result.data;
};
 
const SavedShowAllProgramItemsSchema = z.boolean();
 
export const getSavedShowAllProgramItems = (): boolean => {
  const serializedValue = sessionStorage.getItem(
    SessionStorageValue.MY_PROGRAM_ITEMS_SHOW_ALL_PROGRAM_ITEMS,
  );
 
  const parseJsonResult = StringToJsonSchema.safeParse(serializedValue);
  if (!parseJsonResult.success) {
    return false;
  }
 
  const result = SavedShowAllProgramItemsSchema.safeParse(parseJsonResult.data);
  Iif (!result.success) {
    sessionStorage.removeItem(
      SessionStorageValue.MY_PROGRAM_ITEMS_SHOW_ALL_PROGRAM_ITEMS,
    );
    return false;
  }
 
  return result.data;
};