Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions specifyweb/analyze_cov.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import sys
import json

with open(sys.argv[1]) as f:
cov = json.loads(f.read())

apps = {
key: value["summary"]
for (key, value) in cov["files"].items()
if key.startswith("specifyweb/")
}

data = {}
for key, value in apps.items():
key_split = key.split("/")
assert len(key_split) >= 2
context = data
previous_context = context
for node in key_split[:-1]:
context[node] = context.get(node, dict(report=None, children={}))
context = context[node]["children"]

context[key_split[-1]] = dict(report=value, children={})


def make_report(cov_lines, num_lines):
return dict(
covered_lines=cov_lines,
num_statements=num_lines,
percent_covered=100 if num_lines == 0 else (cov_lines * 100 / num_lines),
)


def get_lines(current_context):
previous_report = current_context["report"]
if previous_report is not None:
return previous_report["covered_lines"], previous_report["num_statements"]
cov_lines = 0
num_stmts = 0
for child in current_context["children"].values():
child_cov_lines, child_num_stmts = get_lines(child)
cov_lines += child_cov_lines
num_stmts += child_num_stmts

current_context["report"] = make_report(cov_lines, num_stmts)
return (cov_lines, num_stmts)


get_lines(data["specifyweb"])

with open("dumped.json", "w") as f:
f.write(json.dumps(data, indent=4))


def _get_tuples(obj):
to_return = [
dict(appName=key, report=value.get("report")) for (key, value) in obj.items()
]

tuples = [
",".join(
[
obj["appName"],
str(obj["report"]["covered_lines"]),
str(obj["report"]["num_statements"]),
str(obj["report"]["percent_covered"]),
]
)
for obj in to_return
]

tuples = [
",".join(["appname", "covered_lines", "num_statements", "percent covered"]),
*tuples,
]

return to_return, tuples


specifyweb_children, tuples = _get_tuples(data["specifyweb"]["children"])


# with open("dumped_per_app.json", "w") as f:

# f.write(json.dumps(specifyweb_children, indent=4))

# with open("/mnt/c/Users/realv/Desktop/specify/apps_report.csv", "w") as f:

# f.write("\n".join(tuples))


specify_app, specify_tuples = _get_tuples(
data["specifyweb"]["children"]["specify"]["children"]
)


with open("dumped_specify_app.json", "w") as f:

f.write(json.dumps(specify_app, indent=4))

with open("/mnt/c/Users/realv/Desktop/specify/apps_report_specify.csv", "w") as f:

f.write("\n".join(specify_tuples))
Original file line number Diff line number Diff line change
Expand Up @@ -893,9 +893,8 @@ describe('treeBusinessRules', () => {
expect(fieldChangeResult.current[0]).toStrictEqual(['Bad tree structure.']);
});
test('saveBlocker not on synonymized parent w/preference', async () => {
const { collectionPreferences } = await import(
'../../Preferences/collectionPreferences'
);
const { collectionPreferences } =
await import('../../Preferences/collectionPreferences');
const originalRaw = collectionPreferences.getRaw();
collectionPreferences.setRaw({
...originalRaw,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,10 @@ export const businessRuleDefs: MappedBusinessRuleDefs = {
return undefined;
},
catalogNumber: async (resource): Promise<undefined> => {
const preferences = await import(
'../Preferences/collectionPreferences'
).then(({ collectionPreferences }) => collectionPreferences);
const preferences =
await import('../Preferences/collectionPreferences').then(
({ collectionPreferences }) => collectionPreferences
);

const uniqueCatalogNumberAccrossComponentAndCOPref = preferences.get(
'uniqueCatalogNumberAccrossComponentAndCO',
Expand Down Expand Up @@ -429,9 +430,10 @@ export const businessRuleDefs: MappedBusinessRuleDefs = {
return undefined;
},
catalogNumber: async (resource): Promise<undefined> => {
const preferences = await import(
'../Preferences/collectionPreferences'
).then(({ collectionPreferences }) => collectionPreferences);
const preferences =
await import('../Preferences/collectionPreferences').then(
({ collectionPreferences }) => collectionPreferences
);

const uniqueCatalogNumberAccrossComponentAndCOPref = preferences.get(
'uniqueCatalogNumberAccrossComponentAndCO',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type ExpressSearchConfigDialogProps = {
readonly isOpen: boolean;
readonly onClose: () => void;
readonly onSave?: () => void;
}
};

export function ExpressSearchConfigDialog({
isOpen,
Expand Down Expand Up @@ -76,7 +76,7 @@ export function ExpressSearchConfigDialog({
isOpen={isOpen}
onClose={onClose}
>
<ExpressSearchConfigEditor
<ExpressSearchConfigEditor
key={String(isOpen)}
onChangeJSON={handleChangeJSON}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,17 @@ import { genericTables } from '../DataModel/tables';

function tableLabel(tableName: string): string {
return (
(genericTables[tableName as keyof typeof genericTables]?.label as string | undefined) ??
camelToHuman(tableName)
(genericTables[tableName as keyof typeof genericTables]?.label as
| string
| undefined) ?? camelToHuman(tableName)
);
}

export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onChangeConfig }: any) {
export function ResultsOrderingTab({
config,
relatedQueriesDefinitions = [],
onChangeConfig,
}: any) {
const baseTables = config.tables
.filter((t: any) => t.searchFields.some((sf: any) => sf.inUse !== false))
.map((t: any) => ({
Expand All @@ -29,8 +34,12 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC
const activeQueries = config.relatedQueries
.filter((rq: any) => rq.isActive)
.map((rq: any) => {
const def = relatedQueriesDefinitions.find((def: any) => def.id === rq.id);
const title = def?.name ? getExpressSearchQueryTitle(def.name) : undefined;
const def = relatedQueriesDefinitions.find(
(def: any) => def.id === rq.id
);
const title = def?.name
? getExpressSearchQueryTitle(def.name)
: undefined;

if (!def || !title || title === String(def.name)) {
return undefined;
Expand Down Expand Up @@ -86,7 +95,9 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC

return (
<div className="flex flex-col gap-2 h-full min-h-[400px]">
<h3 className="font-bold mb-2">{expressSearchConfigText.configureResultsOrdering()}</h3>
<h3 className="font-bold mb-2">
{expressSearchConfigText.configureResultsOrdering()}
</h3>
<p className="text-sm text-gray-500 mb-4">
{expressSearchConfigText.reorderResultsOrderingDescription()}
</p>
Expand All @@ -99,7 +110,10 @@ export function ResultsOrderingTab({ config, relatedQueriesDefinitions = [], onC
>
<span className="font-medium">{item.label}</span>
<div className="flex gap-2">
<Button.BorderedGray disabled={index === 0} onClick={() => moveItem(index, 'up')}>
<Button.BorderedGray
disabled={index === 0}
onClick={() => moveItem(index, 'up')}
>
{icons.chevronUp}
</Button.BorderedGray>
<Button.BorderedGray
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ const mockConfigResponse = {
tableName: 'CollectionObject',
displayOrder: 0,
searchFields: [],
displayFields: []
}
displayFields: [],
},
],
relatedQueries: []
relatedQueries: [],
},
related_queries_definitions: [],
schema_metadata: [
{
name: 'CollectionObject',
title: 'Collection Object',
fields: []
}
]
fields: [],
},
],
};

describe('ExpressSearchConfigEditor', () => {
Expand All @@ -65,42 +65,43 @@ describe('ExpressSearchConfigEditor', () => {
});

expect(onChangeJSON).toHaveBeenCalled();
const latestConfig = onChangeJSON.mock.calls[onChangeJSON.mock.calls.length - 1][0];
const latestConfig =
onChangeJSON.mock.calls[onChangeJSON.mock.calls.length - 1][0];
expect(latestConfig.tables[0].tableName).toBe('Agent');
expect(latestConfig.tables[0].searchFields[0].fieldName).toBe('firstName');
});

test('renders loading state initially', async () => {
const { getByText } = mount(
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
/>
);
expect(getByText('Loading...')).toBeInTheDocument();

// Wait for it to finish loading to avoid act warnings
await act(async () => {
await new Promise(resolve => setTimeout(resolve, 0));
await new Promise((resolve) => setTimeout(resolve, 0));
});
});

test('renders tabs after data load', async () => {
const { findByRole } = mount(
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
/>
);

expect(await findByRole('tablist')).toBeInTheDocument();
});

test('switches tabs correctly', async () => {
const { findByText, getByRole, user } = mount(
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
<ExpressSearchConfigEditor
onChange={jest.fn()}
onSetCleanup={jest.fn()}
/>
);

Expand All @@ -112,7 +113,7 @@ describe('ExpressSearchConfigEditor', () => {
await act(async () => {
await user.click(relatedTab);
});

expect(await findByText('Related Tables Tab')).toBeInTheDocument();

// Click Results Ordering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ describe('RelatedTablesTab', () => {

expect(onChangeConfig).toHaveBeenCalledTimes(1);
const newConfig = onChangeConfig.mock.calls[0][0];
expect(newConfig.relatedQueries.find((rq: any) => rq.id === '2').isActive).toBe(true);
expect(
newConfig.relatedQueries.find((rq: any) => rq.id === '2').isActive
).toBe(true);

const activeRow = rows[0];
const activeCheckbox = activeRow.querySelector('input[type="checkbox"]');
Expand All @@ -54,6 +56,8 @@ describe('RelatedTablesTab', () => {

expect(onChangeConfig).toHaveBeenCalledTimes(2);
const secondConfig = onChangeConfig.mock.calls[1][0];
expect(secondConfig.relatedQueries.find((rq: any) => rq.id === '1').isActive).toBe(false);
expect(
secondConfig.relatedQueries.find((rq: any) => rq.id === '1').isActive
).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ describe('ResultsOrderingTab', () => {
displayFields: [],
},
],
relatedQueries: [
{ id: '8', isActive: true, displayOrder: 1 },
],
relatedQueries: [{ id: '8', isActive: true, displayOrder: 1 }],
};

const onChangeConfig = jest.fn();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ export function FormTable<SCHEMA extends AnySchema>({
resource.cid,
Boolean(
resource.specifyTable.name === 'Preparation' &&
collectionPreparationPref &&
resource.isNew()
collectionPreparationPref &&
resource.isNew()
),
])
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,13 @@ export function usePrimarySearch(
}

async function fetchRelatedSearches(): Promise<RA<string>> {
return contextUnlockedPromise.then(
async (entrypoint) =>
entrypoint === 'main'
? ajax<RA<string>>('/context/available_related_searches.json', {
headers: { Accept: 'application/json' },
cache: 'no-store',
}).then(({ data }) => data)
: foreverFetch<RA<string>>()
return contextUnlockedPromise.then(async (entrypoint) =>
entrypoint === 'main'
? ajax<RA<string>>('/context/available_related_searches.json', {
headers: { Accept: 'application/json' },
cache: 'no-store',
}).then(({ data }) => data)
: foreverFetch<RA<string>>()
);
}

Expand Down
Loading
Loading