Skip to content

Commit

Permalink
fix import (mckaywrigley#242)
Browse files Browse the repository at this point in the history
* 🐛 fix import (mckaywrigley#224)

* 🐛 fix import of corrupted history

see mckaywrigley#224 (comment)

* add the run-test-suite github action
  • Loading branch information
thomasleveil authored Mar 28, 2023
1 parent 5aa5be3 commit b0c289f
Show file tree
Hide file tree
Showing 15 changed files with 13,868 additions and 6,862 deletions.
2 changes: 1 addition & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.env
.env.local
node_modules

test-results
31 changes: 31 additions & 0 deletions .github/workflows/run-test-suite.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Run Jest Tests

on:
push:
branches:
- main
pull_request:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
container:
image: node:16

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Install dependencies
run: npm ci

- name: Run Jest Test Suite
run: npm test

- name: Publish Test Report
if: always()
uses: EnricoMi/publish-unit-test-result-action@v1
with:
files: test-results/**/results.xml
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

# testing
/coverage
/test-results

# next.js
/.next/
Expand Down
156 changes: 156 additions & 0 deletions __tests__/utils/app/importExports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import { ExportFormatV1, ExportFormatV2 } from '@/types/export';
import { OpenAIModels, OpenAIModelID } from '@/types/openai';
import { DEFAULT_SYSTEM_PROMPT } from '@/utils/app/const';
import {
cleanData,
isExportFormatV1,
isExportFormatV2,
isExportFormatV3,
isLatestExportFormat,
} from '@/utils/app/importExport';

describe('Export Format Functions', () => {
describe('isExportFormatV1', () => {
it('should return true for v1 format', () => {
const obj = [{ id: 1 }];
expect(isExportFormatV1(obj)).toBe(true);
});

it('should return false for non-v1 formats', () => {
const obj = { version: 3, history: [], folders: [] };
expect(isExportFormatV1(obj)).toBe(false);
});
});

describe('isExportFormatV2', () => {
it('should return true for v2 format', () => {
const obj = { history: [], folders: [] };
expect(isExportFormatV2(obj)).toBe(true);
});

it('should return false for non-v2 formats', () => {
const obj = { version: 3, history: [], folders: [] };
expect(isExportFormatV2(obj)).toBe(false);
});
});

describe('isExportFormatV3', () => {
it('should return true for v3 format', () => {
const obj = { version: 3, history: [], folders: [] };
expect(isExportFormatV3(obj)).toBe(true);
});

it('should return false for non-v3 formats', () => {
const obj = { version: 4, history: [], folders: [] };
expect(isExportFormatV3(obj)).toBe(false);
});
});
});

describe('cleanData Functions', () => {
describe('cleaning v1 data', () => {
it('should return the latest format', () => {
const data = [
{
id: 1,
name: 'conversation 1',
messages: [
{
role: 'user',
content: "what's up ?",
},
{
role: 'assistant',
content: 'Hi',
},
],
},
] as ExportFormatV1;
const obj = cleanData(data);
expect(isLatestExportFormat(obj)).toBe(true);
expect(obj).toEqual({
version: 3,
history: [
{
id: 1,
name: 'conversation 1',
messages: [
{
role: 'user',
content: "what's up ?",
},
{
role: 'assistant',
content: 'Hi',
},
],
model: OpenAIModels[OpenAIModelID.GPT_3_5],
prompt: DEFAULT_SYSTEM_PROMPT,
folderId: null,
},
],
folders: [],
});
});
});

describe('cleaning v2 data', () => {
it('should return the latest format', () => {
const data = {
history: [
{
id: '1',
name: 'conversation 1',
messages: [
{
role: 'user',
content: "what's up ?",
},
{
role: 'assistant',
content: 'Hi',
},
],
},
],
folders: [
{
id: 1,
name: 'folder 1',
},
],
} as ExportFormatV2;
const obj = cleanData(data);
expect(isLatestExportFormat(obj)).toBe(true);
expect(obj).toEqual({
version: 3,
history: [
{
id: '1',
name: 'conversation 1',
messages: [
{
role: 'user',
content: "what's up ?",
},
{
role: 'assistant',
content: 'Hi',
},
],
model: OpenAIModels[OpenAIModelID.GPT_3_5],
prompt: DEFAULT_SYSTEM_PROMPT,
folderId: null,
},
],
folders: [
{
id: '1',
name: 'folder 1',
type: 'chat',
},
],
});
});
});
});
6 changes: 2 additions & 4 deletions components/Chatbar/Chatbar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Conversation } from '@/types/chat';
import { KeyValuePair } from '@/types/data';
import { SupportedExportFormats } from '@/types/export';
import { Folder } from '@/types/folder';
import {
IconArrowBarLeft,
Expand Down Expand Up @@ -36,10 +37,7 @@ interface Props {
onApiKeyChange: (apiKey: string) => void;
onClearConversations: () => void;
onExportConversations: () => void;
onImportConversations: (data: {
conversations: Conversation[];
folders: Folder[];
}) => void;
onImportConversations: (data: SupportedExportFormats) => void;
}

export const Chatbar: FC<Props> = ({
Expand Down
8 changes: 2 additions & 6 deletions components/Chatbar/ChatbarSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Conversation } from '@/types/chat';
import { Folder } from '@/types/folder';
import { SupportedExportFormats } from '@/types/export';
import { IconFileExport, IconMoon, IconSun } from '@tabler/icons-react';
import { useTranslation } from 'next-i18next';
import { FC } from 'react';
Expand All @@ -16,10 +15,7 @@ interface Props {
onApiKeyChange: (apiKey: string) => void;
onClearConversations: () => void;
onExportConversations: () => void;
onImportConversations: (data: {
conversations: Conversation[];
folders: Folder[];
}) => void;
onImportConversations: (data: SupportedExportFormats) => void;
}

export const ChatbarSettings: FC<Props> = ({
Expand Down
16 changes: 3 additions & 13 deletions components/Settings/Import.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import { Conversation } from '@/types/chat';
import { Folder } from '@/types/folder';
import { cleanConversationHistory } from '@/utils/app/clean';
import { SupportedExportFormats } from '@/types/export';
import { IconFileImport } from '@tabler/icons-react';
import { useTranslation } from 'next-i18next';
import { FC } from 'react';
import { SidebarButton } from '../Sidebar/SidebarButton';

interface Props {
onImport: (data: {
conversations: Conversation[];
folders: Folder[];
}) => void;
onImport: (data: SupportedExportFormats) => void;
}

export const Import: FC<Props> = ({ onImport }) => {
Expand All @@ -30,12 +25,7 @@ export const Import: FC<Props> = ({ onImport }) => {
const reader = new FileReader();
reader.onload = (e) => {
let json = JSON.parse(e.target?.result as string);

if (json && !json.folders) {
json = { history: cleanConversationHistory(json), folders: [] };
}

onImport({ conversations: json.history, folders: json.folders });
onImport(json);
};
reader.readAsText(file);
}}
Expand Down
22 changes: 22 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Config } from 'jest';

const config: Config = {
testEnvironment: 'jest-environment-jsdom',
verbose: true,
preset: 'ts-jest',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
},
reporters: [
'default',
[
'jest-junit',
{
outputDirectory: 'test-results/jest',
outputName: 'results.xml',
},
],
],
};

export default config;
Loading

0 comments on commit b0c289f

Please sign in to comment.