Skip to content

Commit

Permalink
Merge pull request #1296 from BLSQ/IA-2910-IA-2911-Hide-Planning-enti…
Browse files Browse the repository at this point in the history
…tiesrelated-mobile-feature-flag

IA-2910 IA-2911 hide planning and  entitie srelated mobile feature flags
  • Loading branch information
hakifran authored May 13, 2024
2 parents e544c06 + 8cde756 commit 140a07e
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# How to exclude a featureflag related to a module

## 1. Add a new module for which to exclude its related feature flag

- Go to `/hat/menupermissions/constants.py`
- Add to the dictionnary `FEATUREFLAGES_TO_EXCLUDE` a new item
- The key is the name of the module like `DATA_COLLECTION_FORMS` in capitale letter
- The value is a list of featureflags(code in capitale letter) to be excluded like `["FEATUREFLAG_1","FEATUREFLAG_2"]`
- The whole `FEATUREFLAGES_TO_EXCLUDE` should be like `FEATUREFLAGES_TO_EXCLUDE = { "MODULE_1": ["FEATUREFLAG_1"], "MODULE_2": ["FEATUREFLAG_2", "FEATUREFLAG_3"],}`

## 2. Add a feature flag to an existing module to be excluded

- Go to `/hat/menupermissions/constants.py`
- Check the key corresponding to the module
- Add the featureflag code to the value list of the corresponding module(key)
2 changes: 1 addition & 1 deletion hat/assets/js/apps/Iaso/domains/projects/hooks/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export const useGetFeatureFlags = (): UseQueryResult<
// @ts-ignore
return useSnackQuery(
['featureflags'],
() => getRequest('/api/featureflags/'),
() => getRequest('/api/featureflags/except_no_activated_modules/'),
undefined,
{
// using this here to avoid multiple identical calls
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const goToPage = (
interceptFlag = false;
cy.intercept('GET', '/sockjs-node/**');
cy.intercept('GET', '/api/profiles/me/**', fakeUser);
cy.intercept('GET', '/api/featureflags', {
cy.intercept('GET', '/api/featureflags/except_no_activated_modules/', {
fixture: 'featureflags/list.json',
}).as('getFeatureFlags');
const options = {
Expand Down
12 changes: 12 additions & 0 deletions hat/menupermissions/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,15 @@
{"name": "Registry", "codename": "REGISTRY"},
{"name": "Payments", "codename": "PAYMENTS"},
]

FEATUREFLAGES_TO_EXCLUDE = {
"PLANNING": ["PLANNING"],
"ENTITIES": [
"REPORTS",
"ENTITY",
"MOBILE_ENTITY_WARN_WHEN_FOUND",
"MOBILE_ENTITY_LIMITED_SEARCH",
"MOBILE_ENTITY_NO_CREATION",
"WRITE_ON_NFC_CARDS",
],
}
27 changes: 25 additions & 2 deletions iaso/api/feature_flags.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from rest_framework import serializers, permissions

from rest_framework.decorators import action
from rest_framework.response import Response
from iaso.models import FeatureFlag
from .common import ModelViewSet, TimestampField
from hat.menupermissions.constants import FEATUREFLAGES_TO_EXCLUDE
from itertools import chain


class FeatureFlagsSerializer(serializers.ModelSerializer):
Expand All @@ -28,7 +31,27 @@ class FeatureFlagViewSet(ModelViewSet):
results_key = "featureflags"
http_method_names = ["get", "head", "options"]

def get_results_key(self):
return self.results_key

def get_queryset(self):
featureflags = FeatureFlag.objects.all()

return featureflags.order_by("name")

@action(methods=["GET"], detail=False)
def except_no_activated_modules(self, request):
featureflags = self.get_queryset()

current_account = request.user.iaso_profile.account
account_modules = current_account.modules

not_activated_modules = list(set(FEATUREFLAGES_TO_EXCLUDE.keys()) - set(account_modules))
featureflags_to_exclude = list(
chain.from_iterable([FEATUREFLAGES_TO_EXCLUDE[module] for module in not_activated_modules])
)

if featureflags_to_exclude:
featureflags = featureflags.exclude(code__in=featureflags_to_exclude)

serializer = FeatureFlagsSerializer(featureflags, many=True)
return Response({self.get_results_key(): serializer.data})
17 changes: 17 additions & 0 deletions iaso/tests/api/test_projects.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from itertools import chain
import typing

from hat.menupermissions.constants import FEATUREFLAGES_TO_EXCLUDE
from iaso import models as m
from iaso.test import APITestCase

Expand Down Expand Up @@ -57,6 +59,21 @@ def test_feature_flags_list_ok(self):
self.assertJSONResponse(response, 200)
self.assertValidFeatureFlagListData(response.json(), m.FeatureFlag.objects.count())

def test_feature_flags_list_except_no_activated_modules(self):
"""GET /featureflags/except_no_activated_modules happy path: we expect one result"""
self.client.force_authenticate(self.jane)
response = self.client.get(
"/api/featureflags/except_no_activated_modules/", headers={"Content-Type": "application/json"}
)

self.assertJSONResponse(response, 200)
excluded_feature_flags = list(
chain.from_iterable([featureflag for featureflag in FEATUREFLAGES_TO_EXCLUDE.values()])
)
self.assertValidFeatureFlagListData(
response.json(), m.FeatureFlag.objects.count() - len(excluded_feature_flags)
)

def test_projects_list_paginated(self):
"""GET /projects/ paginated happy path"""

Expand Down

0 comments on commit 140a07e

Please sign in to comment.