diff --git a/backend/apps/owasp/index/chapter.py b/backend/apps/owasp/index/chapter.py index 041927ba8..372269d6c 100644 --- a/backend/apps/owasp/index/chapter.py +++ b/backend/apps/owasp/index/chapter.py @@ -16,6 +16,7 @@ class ChapterIndex(AlgoliaIndex): fields = ( "idx_country", "idx_created_at", + "idx_is_active", "idx_key", "idx_leaders", "idx_name", diff --git a/backend/apps/owasp/index/project.py b/backend/apps/owasp/index/project.py index 07c05e074..227c1dd30 100644 --- a/backend/apps/owasp/index/project.py +++ b/backend/apps/owasp/index/project.py @@ -22,6 +22,7 @@ class ProjectIndex(AlgoliaIndex, IndexBase): "idx_forks_count", "idx_issues", "idx_issues_count", + "idx_is_active", "idx_key", "idx_languages", "idx_leaders", diff --git a/backend/apps/owasp/models/chapter.py b/backend/apps/owasp/models/chapter.py index 22217ad8b..9d716b65a 100644 --- a/backend/apps/owasp/models/chapter.py +++ b/backend/apps/owasp/models/chapter.py @@ -72,11 +72,9 @@ def active_chapters_count(): def is_indexable(self): """Chapters to index.""" return ( - self.is_active - and self.latitude is not None + self.latitude is not None and self.longitude is not None and not self.owasp_repository.is_empty - and not self.owasp_repository.is_archived ) def from_github(self, repository): @@ -114,9 +112,6 @@ def generate_geo_location(self): def generate_suggested_location(self, open_ai=None, max_tokens=100): """Generate project summary.""" - if not self.is_active: - return - if not (prompt := Prompt.get_owasp_chapter_suggested_location()): return diff --git a/backend/apps/owasp/models/common.py b/backend/apps/owasp/models/common.py index 7c997aed4..0390d4ee7 100644 --- a/backend/apps/owasp/models/common.py +++ b/backend/apps/owasp/models/common.py @@ -52,7 +52,7 @@ class Meta: @property def is_indexable(self): """Entities to index.""" - return self.is_active and self.has_active_repositories + return self.has_active_repositories @property def github_url(self): @@ -105,7 +105,7 @@ def from_github(self, field_mapping, repository): def generate_summary(self, prompt, open_ai=None, max_tokens=500): """Generate entity summary.""" - if not self.is_active or not prompt: + if not prompt: return open_ai = open_ai or OpenAi() diff --git a/backend/apps/owasp/models/managers/chapter.py b/backend/apps/owasp/models/managers/chapter.py index 4598027b7..9365c4da8 100644 --- a/backend/apps/owasp/models/managers/chapter.py +++ b/backend/apps/owasp/models/managers/chapter.py @@ -12,10 +12,8 @@ def get_queryset(self): return ( super() .get_queryset() - .filter(is_active=True) .select_related("owasp_repository") .filter( - owasp_repository__is_archived=False, owasp_repository__is_empty=False, ) ) diff --git a/backend/apps/owasp/models/mixins/chapter.py b/backend/apps/owasp/models/mixins/chapter.py index 6475e6a5b..4452a0b7a 100644 --- a/backend/apps/owasp/models/mixins/chapter.py +++ b/backend/apps/owasp/models/mixins/chapter.py @@ -21,6 +21,11 @@ def idx_geo_location(self): """Return geographic location for indexing.""" return self.latitude, self.longitude + @property + def idx_is_active(self): + """Return active status for indexing.""" + return self.is_active + @property def idx_key(self): """Return key for indexing.""" diff --git a/backend/apps/owasp/models/mixins/project.py b/backend/apps/owasp/models/mixins/project.py index c31801c3c..99818d6e7 100644 --- a/backend/apps/owasp/models/mixins/project.py +++ b/backend/apps/owasp/models/mixins/project.py @@ -60,6 +60,11 @@ def idx_issues_count(self): """Return issues count for indexing.""" return self.open_issues.count() + @property + def idx_is_active(self): + """Return active status for indexing.""" + return self.is_active + @property def idx_key(self): """Return key for indexing.""" diff --git a/backend/apps/owasp/models/project.py b/backend/apps/owasp/models/project.py index 9f6e09df7..b54a4b2a9 100644 --- a/backend/apps/owasp/models/project.py +++ b/backend/apps/owasp/models/project.py @@ -142,7 +142,7 @@ def is_tool_type(self): @property def is_indexable(self): """Projects to index.""" - return self.is_active and self.has_active_repositories + return self.has_active_repositories @property def nest_key(self): diff --git a/backend/tests/owasp/models/chapter_tests.py b/backend/tests/owasp/models/chapter_tests.py index 4af0eb79c..7ce0d7a7e 100644 --- a/backend/tests/owasp/models/chapter_tests.py +++ b/backend/tests/owasp/models/chapter_tests.py @@ -85,16 +85,10 @@ def test_generate_suggested_location( assert chapter.suggested_location == (expected_location or "") - if is_active: - mock_open_ai.set_input.assert_called_once_with(geo_string) - mock_open_ai.set_max_tokens.assert_called_once_with(100) - mock_open_ai.set_prompt.assert_called_once_with("Tell me the location") - mock_open_ai.complete.assert_called_once() - else: - mock_open_ai.set_input.assert_not_called() - mock_open_ai.set_max_tokens.assert_not_called() - mock_open_ai.set_prompt.assert_not_called() - mock_open_ai.complete.assert_not_called() + mock_open_ai.set_input.assert_called_once_with(geo_string) + mock_open_ai.set_max_tokens.assert_called_once_with(100) + mock_open_ai.set_prompt.assert_called_once_with("Tell me the location") + mock_open_ai.complete.assert_called_once() @pytest.mark.parametrize( ("name", "key", "expected_str"), diff --git a/backend/tests/owasp/models/common_tests.py b/backend/tests/owasp/models/common_tests.py index 6a747c067..3eb53b412 100644 --- a/backend/tests/owasp/models/common_tests.py +++ b/backend/tests/owasp/models/common_tests.py @@ -13,17 +13,14 @@ class Meta: class TestRepositoryBasedEntityModel: @pytest.mark.parametrize( - ("is_active", "has_active_repositories", "expected"), + ("has_active_repositories", "expected"), [ - (True, True, True), - (True, False, False), - (False, True, False), - (False, False, False), + (True, True), + (False, False), ], ) - def test_is_indexable(self, is_active, has_active_repositories, expected): + def test_is_indexable(self, has_active_repositories, expected): model = EntityModel() - model.is_active = is_active model.has_active_repositories = has_active_repositories assert model.is_indexable == expected diff --git a/frontend/__tests__/src/data/mockChapterData.ts b/frontend/__tests__/src/data/mockChapterData.ts index 614646771..db5650e1f 100644 --- a/frontend/__tests__/src/data/mockChapterData.ts +++ b/frontend/__tests__/src/data/mockChapterData.ts @@ -23,6 +23,7 @@ export const mockChapterData = { key: 'chapter_1', url: 'https://owasp.org/www-chapter-nagoya', objectID: '539', + is_active: true, }, ], } diff --git a/frontend/__tests__/src/data/mockProjectData.ts b/frontend/__tests__/src/data/mockProjectData.ts index 666648a20..a355aa5c2 100644 --- a/frontend/__tests__/src/data/mockProjectData.ts +++ b/frontend/__tests__/src/data/mockProjectData.ts @@ -14,6 +14,7 @@ export const mockProjectData = { key: 'project_1', stars_count: 20, contributors_count: 5, + is_active: true, }, ], } diff --git a/frontend/__tests__/src/data/mockProjectDetailsData.ts b/frontend/__tests__/src/data/mockProjectDetailsData.ts index a168e9343..059d4fd12 100644 --- a/frontend/__tests__/src/data/mockProjectDetailsData.ts +++ b/frontend/__tests__/src/data/mockProjectDetailsData.ts @@ -11,6 +11,7 @@ export const mockProjectDetailsData = { forks_count: 20, stars_count: 100, issues_count: 10, + is_active: true, repositories_count: 2, summary: 'This is a summary of the test project.', languages: Array.from({ length: 15 }, (_, i) => `Language ${i + 1}`), diff --git a/frontend/src/pages/ChapterDetails.tsx b/frontend/src/pages/ChapterDetails.tsx index ea8aa8794..555aeb54e 100644 --- a/frontend/src/pages/ChapterDetails.tsx +++ b/frontend/src/pages/ChapterDetails.tsx @@ -33,7 +33,7 @@ const ChapterDetailsPage = () => { ) - if (!chapter) + if (!chapter || !chapter.is_active) return ( { topContributors={chapter.top_contributors} button={SubmitButton} social={formattedUrls} + isActive={chapter.is_active} /> diff --git a/frontend/src/pages/ProjectDetails.tsx b/frontend/src/pages/ProjectDetails.tsx index cf06fe2c9..1c3e0bec5 100644 --- a/frontend/src/pages/ProjectDetails.tsx +++ b/frontend/src/pages/ProjectDetails.tsx @@ -72,6 +72,9 @@ const ProjectDetailsPage = () => {

{project.name}

+ {!project.is_active && ( + Inactive + )}

{project.description}

Summary

diff --git a/frontend/src/pages/Projects.tsx b/frontend/src/pages/Projects.tsx index 1a21c2dc9..1d7dc3d34 100644 --- a/frontend/src/pages/Projects.tsx +++ b/frontend/src/pages/Projects.tsx @@ -74,7 +74,7 @@ const ProjectsPage = () => { /> } > - {projects && projects.map(renderProjectCard)} + {projects && projects.filter((project) => project.is_active).map(renderProjectCard)} ) } diff --git a/frontend/src/types/card.ts b/frontend/src/types/card.ts index 3d21b12bb..add8a44cd 100644 --- a/frontend/src/types/card.ts +++ b/frontend/src/types/card.ts @@ -22,4 +22,5 @@ export interface CardProps { projectLink?: string social?: { title: string; icon: string; url: string }[] tooltipLabel?: string + isActive?: boolean } diff --git a/frontend/src/types/chapter.ts b/frontend/src/types/chapter.ts index 255a39792..45c16b945 100644 --- a/frontend/src/types/chapter.ts +++ b/frontend/src/types/chapter.ts @@ -1,5 +1,6 @@ export interface ChapterType { created_at: number + is_active: boolean key: string leaders: string[] name: string diff --git a/frontend/src/types/project.ts b/frontend/src/types/project.ts index 955839aa0..eec79e5a1 100644 --- a/frontend/src/types/project.ts +++ b/frontend/src/types/project.ts @@ -7,6 +7,7 @@ export type project = { }[] contributors_count: number forks_count: number + is_active: boolean leaders: string[] level: string name: string diff --git a/frontend/src/utils/paramsMapping.ts b/frontend/src/utils/paramsMapping.ts index 5331b7a78..3fb427ccb 100644 --- a/frontend/src/utils/paramsMapping.ts +++ b/frontend/src/utils/paramsMapping.ts @@ -22,6 +22,7 @@ export const getParamsForIndexName = (indexName: string, distinct = false) => { return { attributesToRetrieve: [ 'idx_created_at', + 'idx_is_active', 'idx_key', 'idx_leaders', 'idx_name', @@ -44,6 +45,7 @@ export const getParamsForIndexName = (indexName: string, distinct = false) => { 'idx_forks_count', 'idx_issues', 'idx_issues_count', + 'idx_is_active', 'idx_key', 'idx_languages', 'idx_leaders',