mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
fix(mobile): prepare v1.0.7 OTA release
This commit is contained in:
1 parent
2664791233
commit
db5980c9bd
16 files changed
+221
-61
No files matched your search
@@ -0,0 +1,46 @@
|
||||
const configPath = require.resolve("../../app.config");
|
||||
|
||||
type UpdateConfig = {
|
||||
updates: {
|
||||
codeSigningCertificate?: string;
|
||||
codeSigningMetadata?: Record<string, string>;
|
||||
};
|
||||
};
|
||||
|
||||
function resolveConfig(environment: Record<string, string>): UpdateConfig {
|
||||
const previous = {
|
||||
DISABLE_CODE_SIGNING: process.env.DISABLE_CODE_SIGNING,
|
||||
RELEASE_CHANNEL: process.env.RELEASE_CHANNEL,
|
||||
};
|
||||
|
||||
Object.assign(process.env, environment);
|
||||
jest.resetModules();
|
||||
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
return (require(configPath) as () => UpdateConfig)();
|
||||
} finally {
|
||||
for (const [key, value] of Object.entries(previous)) {
|
||||
if (value === undefined) {
|
||||
delete process.env[key];
|
||||
} else {
|
||||
process.env[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
describe("Expo OTA configuration", () => {
|
||||
it("rejects disabling code signing for a production build", () => {
|
||||
expect(() =>
|
||||
resolveConfig({ RELEASE_CHANNEL: "production", DISABLE_CODE_SIGNING: "1" }),
|
||||
).toThrow("RELEASE_CHANNEL=production does not permit DISABLE_CODE_SIGNING");
|
||||
});
|
||||
|
||||
it("keeps local development code-signing opt-out available", () => {
|
||||
const config = resolveConfig({ RELEASE_CHANNEL: "development", DISABLE_CODE_SIGNING: "1" });
|
||||
|
||||
expect(config.updates.codeSigningCertificate).toBeUndefined();
|
||||
expect(config.updates.codeSigningMetadata).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@@ -112,6 +112,7 @@ describe("authStore", () => {
|
||||
});
|
||||
|
||||
it("clears user-scoped stores and hosted auth when the API rejects the session", async () => {
|
||||
useAuthStore.setState({ sealedCount: 3 } as any);
|
||||
(authClient.auth.getSession as jest.Mock).mockResolvedValueOnce({
|
||||
data: { session: { user: { id: "me" } } },
|
||||
});
|
||||
@@ -122,6 +123,7 @@ describe("authStore", () => {
|
||||
|
||||
expect(useAuthStore.getState()).toMatchObject({
|
||||
user: null,
|
||||
sealedCount: 0,
|
||||
isAuthenticated: false,
|
||||
isAnonymous: false,
|
||||
isLoading: false,
|
||||
@@ -132,4 +134,28 @@ describe("authStore", () => {
|
||||
expect(useSubscriptionStore.getState().subscription).toMatchObject({ isProUser: false });
|
||||
expect(authClient.auth.signOut).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears sealed answers during an explicit sign-out", async () => {
|
||||
useAuthStore.setState({ user: profile, sealedCount: 3, isAuthenticated: true } as any);
|
||||
|
||||
await useAuthStore.getState().signOut();
|
||||
|
||||
expect(useAuthStore.getState()).toMatchObject({
|
||||
user: null,
|
||||
sealedCount: 0,
|
||||
isAuthenticated: false,
|
||||
});
|
||||
});
|
||||
|
||||
it("clears sealed answers when the auth listener clears the user", () => {
|
||||
useAuthStore.setState({ user: profile, sealedCount: 3, isAuthenticated: true } as any);
|
||||
|
||||
useAuthStore.getState().setUser(null);
|
||||
|
||||
expect(useAuthStore.getState()).toMatchObject({
|
||||
user: null,
|
||||
sealedCount: 0,
|
||||
isAuthenticated: false,
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -88,7 +88,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
} catch (error) {
|
||||
if (error instanceof ApiError && error.status === 401) {
|
||||
console.log("[Auth] Session rejected by API, signing out");
|
||||
set({ user: null, couple: null, partner: null, isAuthenticated: false, isAnonymous: false, isLoading: false });
|
||||
set({ user: null, couple: null, partner: null, sealedCount: 0, isAuthenticated: false, isAnonymous: false, isLoading: false });
|
||||
const { useMatchStore, usePacksStore, useMessageStore, useSubscriptionStore, useNotificationPreferencesStore, useStreakStore, useResponsesStore, useQuizStore } = getOtherStores();
|
||||
useMatchStore.getState().clearMatches();
|
||||
usePacksStore.getState().clearPacks();
|
||||
@@ -137,6 +137,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
user: null,
|
||||
couple: null,
|
||||
partner: null,
|
||||
sealedCount: 0,
|
||||
isAuthenticated: false,
|
||||
isAnonymous: false,
|
||||
isLoading: false,
|
||||
@@ -171,7 +172,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
...(user === null && { isAnonymous: false }),
|
||||
isLoading: false,
|
||||
// Clear couple/partner when user is null (signed out)
|
||||
...(user === null && { couple: null, partner: null })
|
||||
...(user === null && { couple: null, partner: null, sealedCount: 0 })
|
||||
});
|
||||
// Clear other stores when user signs out
|
||||
if (user === null) {
|
||||
@@ -211,4 +212,3 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
||||
void syncTimezone(userId);
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in new issue
Block a user