managarten/apps-archived/maerchenzauber/apps/backend/test/supabase-migration-test.ts
Till-JS 61d181fbc2 chore: archive inactive projects to apps-archived/
Move inactive projects out of active workspace:
- bauntown (community website)
- maerchenzauber (AI story generation)
- memoro (voice memo app)
- news (news aggregation)
- nutriphi (nutrition tracking)
- reader (reading app)
- uload (URL shortener)
- wisekeep (AI wisdom extraction)

Update CLAUDE.md documentation:
- Add presi to active projects
- Document archived projects section
- Update workspace configuration

Archived apps can be re-activated by moving back to apps/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 07:03:59 +01:00

295 lines
8.8 KiB
TypeScript

import { Test } from '@nestjs/testing';
import { AppModule } from '../src/app.module';
import { SupabaseJsonbService } from '../src/core/services/supabase-jsonb.service';
import { randomUUID } from 'crypto';
import { CustomFirestoreService } from '../src/core/services/firestore.service';
import { SettingsService } from '../src/core/services/settings.service';
import { SupabaseProvider } from '../src/supabase/supabase.provider';
import * as admin from 'firebase-admin';
// Initialize Firebase with mock credentials for testing
function initializeFirebase() {
try {
// Check if Firebase is already initialized
admin.app();
console.log('Firebase already initialized');
} catch (error) {
// Initialize Firebase with a minimal app
admin.initializeApp({
projectId: 'test-project',
});
console.log('Firebase initialized with mock app');
}
}
// Create mock for Firebase Firestore
class MockFirestore {
collection() {
return this;
}
doc() {
return this;
}
get() {
return Promise.resolve({
exists: true,
data: () => ({
replicateModel: 'test-model',
authorPrompts: {},
illustratorPrompts: {},
}),
});
}
set() {
return Promise.resolve();
}
update() {
return Promise.resolve();
}
delete() {
return Promise.resolve();
}
}
async function runTests() {
// Initialize Firebase before creating the test module
initializeFirebase();
// Create a mock database to store data between operations
const mockDatabase = {
characters: new Map(),
stories: new Map(),
};
// Mock Supabase client
const mockSupabaseClient = {
from: (table: string) => ({
select: (columns = '*') => ({
eq: (column: string, value: any) => ({
single: () => {
if (table === 'characters' && mockDatabase.characters.has(value)) {
return Promise.resolve({
data: mockDatabase.characters.get(value),
error: null,
});
} else if (table === 'stories' && mockDatabase.stories.has(value)) {
return Promise.resolve({
data: mockDatabase.stories.get(value),
error: null,
});
}
return Promise.resolve({ data: null, error: null });
},
maybeSingle: () => Promise.resolve({ data: null, error: null }),
order: () => Promise.resolve({ data: [], error: null }),
limit: () => Promise.resolve({ data: [], error: null }),
}),
order: () => ({
limit: () => Promise.resolve({ data: [], error: null }),
}),
limit: () => Promise.resolve({ data: [], error: null }),
}),
insert: (items: any[]) => ({
select: () => {
if (table === 'characters') {
const item = { ...items[0] };
mockDatabase.characters.set(item.id, item);
return Promise.resolve({ data: [item], error: null });
} else if (table === 'stories') {
const item = { ...items[0] };
mockDatabase.stories.set(item.id, item);
return Promise.resolve({ data: [item], error: null });
}
return Promise.resolve({ data: items, error: null });
},
}),
update: (data: any) => ({
eq: (column: string, value: string) => {
if (table === 'characters' && mockDatabase.characters.has(value)) {
const item = mockDatabase.characters.get(value);
const updatedItem = { ...item, ...data };
mockDatabase.characters.set(value, updatedItem);
return Promise.resolve({ data: [updatedItem], error: null });
} else if (table === 'stories' && mockDatabase.stories.has(value)) {
const item = mockDatabase.stories.get(value);
const updatedItem = { ...item, ...data };
mockDatabase.stories.set(value, updatedItem);
return Promise.resolve({ data: [updatedItem], error: null });
}
return Promise.resolve({ data: [], error: null });
},
match: () => Promise.resolve({ data: {}, error: null }),
}),
delete: () => ({
eq: (column: string, value: string) => {
if (table === 'characters') {
mockDatabase.characters.delete(value);
} else if (table === 'stories') {
mockDatabase.stories.delete(value);
}
return Promise.resolve({ data: {}, error: null });
},
match: () => Promise.resolve({ data: {}, error: null }),
}),
upsert: () => Promise.resolve({ data: {}, error: null }),
}),
storage: {
from: () => ({
upload: () => Promise.resolve({ data: {}, error: null }),
getPublicUrl: () => ({
data: { publicUrl: 'https://example.com/test.jpg' },
}),
}),
},
auth: {
setSession: () => {},
},
};
// Create a test NestJS application with mocked services
const moduleRef = await Test.createTestingModule({
imports: [AppModule],
})
.overrideProvider(CustomFirestoreService)
.useValue({
firestore: new MockFirestore(),
getCharacterData: () => Promise.resolve({ data: {}, error: null }),
getStoryData: () => Promise.resolve({ data: {}, error: null }),
saveStory: () => Promise.resolve({ data: {}, error: null }),
saveCharacter: () => Promise.resolve({ data: {}, error: null }),
})
.overrideProvider(SettingsService)
.useValue({
prompts: { author: {}, illustrator: {} },
getAuthorPrompt: () => 'Test author prompt',
getIllustratorPrompt: () => 'Test illustrator prompt',
getReplicateModel: () => 'test-model',
getCreators: () => [],
getCreatorById: () => null,
initialize: () => Promise.resolve(),
})
.overrideProvider(SupabaseProvider)
.useValue({
getClient: () => mockSupabaseClient,
})
.compile();
const app = moduleRef.createNestApplication();
await app.init();
// Get the SupabaseJsonbService instance
const supabaseService = app.get<SupabaseJsonbService>(SupabaseJsonbService);
// Test user ID - use a real user ID or create a special test user
const testUserId = 'test-user-' + randomUUID().substring(0, 8);
try {
console.log('=== SUPABASE MIGRATION TEST ===');
console.log(`Using test user ID: ${testUserId}`);
// Test 1: Create a character
console.log('\n--- Test 1: Create a character ---');
const characterId = randomUUID();
const characterData = {
id: characterId,
name: 'Test Character',
images_data: [
{
description: 'Test image description',
image_url: 'https://example.com/test.jpg',
},
],
original_description: 'A test character',
character_description_prompt: 'A test character for Supabase migration',
image_url: 'https://example.com/test.jpg',
created_at: new Date().toISOString(),
is_animal: false,
};
const character = await supabaseService.createCharacter(testUserId, characterData);
console.log('Created character:', character ? 'Success' : 'Failed');
// Test 2: Retrieve the character
console.log('\n--- Test 2: Retrieve the character ---');
const retrievedCharacter = await supabaseService.getCharacterById(characterId);
console.log('Retrieved character:', retrievedCharacter ? 'Success' : 'Failed');
console.log(
'Character data matches:',
retrievedCharacter &&
retrievedCharacter.name === characterData.name &&
retrievedCharacter.original_description === characterData.original_description
? 'Yes'
: 'No'
);
// Test 3: Create a story
console.log('\n--- Test 3: Create a story ---');
const storyId = randomUUID();
const storyData = {
id: storyId,
title: 'Test Story',
description: 'A test story for Supabase migration',
pages_data: [
{
page_number: 1,
story_text: 'Once upon a time...',
illustration_description: 'A beautiful landscape',
image_url: 'https://example.com/illustration1.jpg',
},
{
page_number: 2,
story_text: 'There was a brave character...',
illustration_description: 'A character standing tall',
image_url: 'https://example.com/illustration2.jpg',
},
],
characters_data: [
{
character_description: 'A brave character',
pages: [1, 2],
},
],
combined_story: 'Once upon a time... There was a brave character...',
created_at: new Date().toISOString(),
user_id: testUserId,
character_ids: [characterId],
};
const story = await supabaseService.createStory(testUserId, storyData);
console.log('Created story:', story ? 'Success' : 'Failed');
// Test 4: Retrieve the story
console.log('\n--- Test 4: Retrieve the story ---');
const retrievedStory = await supabaseService.getStoryById(storyId);
console.log('Retrieved story:', retrievedStory ? 'Success' : 'Failed');
console.log(
'Story data matches:',
retrievedStory &&
retrievedStory.title === storyData.title &&
retrievedStory.pages_data.length === storyData.pages_data.length
? 'Yes'
: 'No'
);
console.log('\n=== TEST SUMMARY ===');
console.log('All tests completed. Check above logs for details.');
} catch (error) {
console.error('Test failed with error:', error);
} finally {
// Clean up
await app.close();
}
}
// Run the tests
runTests()
.then(() => {
console.log('Tests completed');
process.exit(0);
})
.catch((error) => {
console.error('Test script failed:', error);
process.exit(1);
});