Skip to content

Commit

Permalink
fix: [#176740861] Remove from store/readState a not found service (#2868
Browse files Browse the repository at this point in the history
)

* [#176740861] add reducer logic and tests

* [#176740861] update comment

Co-authored-by: Cristiano Tofani <[email protected]>
  • Loading branch information
Undermaken and CrisTofani authored Mar 17, 2021
1 parent 6e44188 commit 64c4a41
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
5 changes: 5 additions & 0 deletions ts/sagas/startup/loadServiceDetailRequestHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Millisecond } from "italia-ts-commons/lib/units";
import { BackendClient } from "../../api/backend";
import {
loadServiceDetail,
loadServiceDetailNotFound,
loadServicesDetail
} from "../../store/actions/services";
import { SagaCallReturnType } from "../../types/utils";
Expand All @@ -14,6 +15,7 @@ import { handleServiceReadabilitySaga } from "../services/handleServiceReadabili
import { totServiceFetchWorkers } from "../../config";
import { applicationChangeState } from "../../store/actions/application";
import { mixpanelTrack } from "../../mixpanel";
import { ServiceId } from "../../../definitions/backend/ServiceId";

/**
* A generator to load the service details from the Backend
Expand Down Expand Up @@ -43,6 +45,9 @@ export function* loadServiceDetailRequestHandler(
// Update, if needed, the name of the organization that provides the service
yield call(handleOrganizationNameUpdateSaga, response.value.value);
} else {
if (response.value.status === 404) {
yield put(loadServiceDetailNotFound(action.payload as ServiceId));
}
throw Error(`response status ${response.value.status}`);
}
} catch (error) {
Expand Down
7 changes: 6 additions & 1 deletion ts/store/actions/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ type ServiceLoadFailurePayload = {
service_id: string;
};

// a specific action used when a requested service is not found
export const loadServiceDetailNotFound = createStandardAction(
"LOAD_SERVICE_DETAIL_NOT_FOUND"
)<ServiceId>();
export const loadServiceDetail = createAsyncAction(
"LOAD_SERVICE_DETAIL_REQUEST",
"LOAD_SERVICE_DETAIL_SUCCESS",
Expand Down Expand Up @@ -78,4 +82,5 @@ export type ServicesActions =
| ActionType<typeof loadServicesDetail>
| ActionType<typeof markServiceAsRead>
| ActionType<typeof removeServiceTuples>
| ActionType<typeof showServiceDetails>;
| ActionType<typeof showServiceDetails>
| ActionType<typeof loadServiceDetailNotFound>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { OrganizationFiscalCode } from "italia-ts-commons/lib/strings";
import { appReducer } from "../../../index";
import {
loadServiceDetailNotFound,
markServiceAsRead,
showServiceDetails
} from "../../../../actions/services";
import { ServicePublic } from "../../../../../../definitions/backend/ServicePublic";
import { ServiceId } from "../../../../../../definitions/backend/ServiceId";
import { ServiceName } from "../../../../../../definitions/backend/ServiceName";
import { NotificationChannelEnum } from "../../../../../../definitions/backend/NotificationChannel";
import { OrganizationName } from "../../../../../../definitions/backend/OrganizationName";
import { DepartmentName } from "../../../../../../definitions/backend/DepartmentName";

const mockService: ServicePublic = {
department_name: "dev department name" as DepartmentName,
organization_fiscal_code: "00000000001" as OrganizationFiscalCode,
organization_name: "Ramella, Zanetti and Maggiani [1]" as OrganizationName,
service_id: "id1" as ServiceId,
service_name: "reinventate next-generation architetture" as ServiceName,
available_notification_channels: [NotificationChannelEnum.EMAIL],
version: 1
};

describe("readServicesByIdReducer", () => {
it("should be read", () => {
const state = appReducer(undefined, showServiceDetails(mockService));
expect(state.entities.services.readState.id1).toBeTruthy();
});

it("should be read", () => {
const state = appReducer(undefined, markServiceAsRead("id2" as ServiceId));
expect(state.entities.services.readState.id2).toBeTruthy();
});

it("should be undefined", () => {
const state = appReducer(undefined, showServiceDetails(mockService));
expect(state.entities.services.readState.id3).toBeUndefined();
});

it("should remove a specific not found service read state", () => {
const state1 = appReducer(undefined, markServiceAsRead("id1" as ServiceId));
const state2 = appReducer(state1, markServiceAsRead("id2" as ServiceId));
expect(state2.entities.services.readState.id1).toBeTruthy();
expect(state2.entities.services.readState.id2).toBeTruthy();
const updateState = appReducer(
state2,
loadServiceDetailNotFound("id1" as ServiceId)
);
expect(updateState.entities.services.readState.id1).toBeUndefined();
expect(state2.entities.services.readState.id2).toBeTruthy();
});
});
4 changes: 4 additions & 0 deletions ts/store/reducers/entities/services/readStateByServiceId.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { getType } from "typesafe-actions";
import _ from "lodash";
import {
loadServiceDetailNotFound,
markServiceAsRead,
showServiceDetails
} from "../../../actions/services";
Expand Down Expand Up @@ -36,6 +38,8 @@ export function readServicesByIdReducer(
...state,
[action.payload]: true
};
case getType(loadServiceDetailNotFound):
return _.omit(state, [action.payload]);
// reset reading state if current profile is different from the previous one
case getType(differentProfileLoggedIn):
return INITIAL_STATE;
Expand Down

0 comments on commit 64c4a41

Please sign in to comment.