diff --git a/src/sagas/communities/launchCommunity/launchCommunity.saga.test.ts b/src/sagas/communities/launchCommunity/launchCommunity.saga.test.ts index e550ade..f497822 100644 --- a/src/sagas/communities/launchCommunity/launchCommunity.saga.test.ts +++ b/src/sagas/communities/launchCommunity/launchCommunity.saga.test.ts @@ -59,10 +59,31 @@ describe('launchCommunity', () => { port: 0, }; + const identityAlpha: Identity = { + id: 'communityAlpha', + zbayNickname: 'nickname', + hiddenService: { + onionAddress: '', + privateKey: '', + }, + dmKeys: { + publicKey: '', + privateKey: '', + }, + peerId: { + id: '', + pubKey: '', + privKey: '', + }, + userCsr: null, + userCertificate: 'userCert', + }; + await expectSaga(initCommunities) .withReducer( combineReducers({ [StoreKeys.Communities]: communitiesReducer, + [StoreKeys.Identity]: identityReducer, }), { [StoreKeys.Communities]: { @@ -73,6 +94,13 @@ describe('launchCommunity', () => { [community1, community2, community3] ), }, + [StoreKeys.Identity]: { + ...new IdentityState(), + identities: identityAdapter.setAll( + identityAdapter.getInitialState(), + [identityAlpha] + ), + }, } ) .put(communitiesActions.launchCommunity(community1.id)) diff --git a/src/sagas/communities/launchCommunity/launchCommunity.saga.ts b/src/sagas/communities/launchCommunity/launchCommunity.saga.ts index e9aab26..634a5cc 100644 --- a/src/sagas/communities/launchCommunity/launchCommunity.saga.ts +++ b/src/sagas/communities/launchCommunity/launchCommunity.saga.ts @@ -6,10 +6,19 @@ import { identitySelectors } from '../../identity/identity.selectors'; import { communitiesSelectors } from '../communities.selectors'; import { communitiesActions } from '../communities.slice'; +import { identityActions } from '../../identity/identity.slice'; export function* initCommunities(): Generator { - const communities = yield* select(communitiesSelectors.allCommunities); - for (const community of communities) { + + const joinedCommunities = yield* select(identitySelectors.joinedCommunities); + const unregisteredCommunities = yield* select(identitySelectors.unregisteredCommunities) + const userName = yield* select(identitySelectors.currentIdentity) + + for (const community of unregisteredCommunities) { + yield* put(identityActions.registerUsername(userName.zbayNickname)); + } + + for (const community of joinedCommunities) { yield* put(communitiesActions.launchCommunity(community.id)); } } diff --git a/src/sagas/identity/identity.selectors.test.ts b/src/sagas/identity/identity.selectors.test.ts new file mode 100644 index 0000000..c62865f --- /dev/null +++ b/src/sagas/identity/identity.selectors.test.ts @@ -0,0 +1,254 @@ +import { combineReducers, createStore, Store } from '@reduxjs/toolkit'; +import { StoreKeys } from '../store.keys'; +import { communitiesAdapter } from './../communities/communities.adapter'; +import { + communitiesReducer, + CommunitiesState, + Community, +} from './../communities/communities.slice'; +import { identityAdapter } from './identity.adapter'; +import { identitySelectors } from './identity.selectors'; +import { Identity, identityReducer, IdentityState } from './identity.slice'; + +describe('communitiesSelectors', () => { + let store: Store; + const communityAlpha: Community = { + name: 'alpha', + id: 'communityAlpha', + CA: { rootCertString: 'certString', rootKeyString: 'keyString' }, + registrarUrl: '', + rootCa: '', + peerList: [], + registrar: null, + onionAddress: '', + privateKey: '', + port: 0, + }; + const communityBeta: Community = { + name: 'beta', + id: 'communityBeta', + CA: { rootCertString: 'certString', rootKeyString: 'keyString' }, + registrarUrl: '', + rootCa: '', + peerList: [], + registrar: null, + onionAddress: '', + privateKey: '', + port: 0, + }; + + const communityDelta: Community = { + name: 'beta', + id: 'communityDelta', + CA: { rootCertString: 'certString', rootKeyString: 'keyString' }, + registrarUrl: '', + rootCa: '', + peerList: [], + registrar: null, + onionAddress: '', + privateKey: '', + port: 0, + }; + + const identityAlpha: Identity = { + id: 'communityAlpha', + zbayNickname: 'nickname', + hiddenService: { + onionAddress: '', + privateKey: '', + }, + dmKeys: { + publicKey: '', + privateKey: '', + }, + peerId: { + id: '', + pubKey: '', + privKey: '', + }, + userCsr: null, + userCertificate: 'userCert', + }; + + const identityBeta: Identity = { + id: 'communityBeta', + zbayNickname: 'nickname', + hiddenService: { + onionAddress: '', + privateKey: '', + }, + dmKeys: { + publicKey: '', + privateKey: '', + }, + peerId: { + id: '', + pubKey: '', + privKey: '', + }, + userCsr: null, + userCertificate: 'userCert', + }; + + const identityDelta: Identity = { + id: 'communityDelta', + zbayNickname: 'nickname', + hiddenService: { + onionAddress: '', + privateKey: '', + }, + dmKeys: { + publicKey: '', + privateKey: '', + }, + peerId: { + id: '', + pubKey: '', + privKey: '', + }, + userCsr: null, + userCertificate: null, + }; + + beforeEach(() => { + store = createStore( + combineReducers({ + [StoreKeys.Communities]: communitiesReducer, + [StoreKeys.Identity]: identityReducer, + }), + { + [StoreKeys.Communities]: { + ...new CommunitiesState(), + currentCommunity: 'communityBeta', + communities: communitiesAdapter.setAll( + communitiesAdapter.getInitialState(), + [communityAlpha, communityBeta, communityDelta] + ), + }, + [StoreKeys.Identity]: { + ...new IdentityState(), + identities: identityAdapter.setAll( + identityAdapter.getInitialState(), + [identityBeta, identityDelta] + ), + }, + } + ); + }); + + it('select current id', () => { + const currentIdentity = identitySelectors.currentIdentity(store.getState()); + + expect(currentIdentity).toMatchInlineSnapshot(` + Object { + "dmKeys": Object { + "privateKey": "", + "publicKey": "", + }, + "hiddenService": Object { + "onionAddress": "", + "privateKey": "", + }, + "id": "communityBeta", + "peerId": Object { + "id": "", + "privKey": "", + "pubKey": "", + }, + "userCertificate": "userCert", + "userCsr": null, + "zbayNickname": "nickname", + } + `); + }); + + it('select joined communities with user identity with certificate', () => { + const joinedCommunities = identitySelectors.joinedCommunities( + store.getState() + ); + const idOfJoinedCommunities = joinedCommunities.map( + (community) => community.id + ); + + expect(idOfJoinedCommunities).toEqual(['communityBeta']); + expect(joinedCommunities).toMatchInlineSnapshot(` +Array [ + Object { + "CA": Object { + "rootCertString": "certString", + "rootKeyString": "keyString", + }, + "id": "communityBeta", + "name": "beta", + "onionAddress": "", + "peerList": Array [], + "port": 0, + "privateKey": "", + "registrar": null, + "registrarUrl": "", + "rootCa": "", + }, +] +`); + }); + + it('select unregistered communities with user identity without certificate', () => { + const unregisteredCommunities = identitySelectors.unregisteredCommunities( + store.getState() + ); + const idOfJoinedCommunities = unregisteredCommunities.map( + (community) => community.id + ); + + expect(idOfJoinedCommunities).toEqual(['communityDelta']); + expect(unregisteredCommunities).toMatchInlineSnapshot(` +Array [ + Object { + "CA": Object { + "rootCertString": "certString", + "rootKeyString": "keyString", + }, + "id": "communityDelta", + "name": "beta", + "onionAddress": "", + "peerList": Array [], + "port": 0, + "privateKey": "", + "registrar": null, + "registrarUrl": "", + "rootCa": "", + }, +] +`); + }); + + it('select communities without user identity', () => { + const unregisteredCommunities = identitySelectors.unregisteredCommunitiesWithoutUserIdentity( + store.getState() + ); + const idOfJoinedCommunities = unregisteredCommunities.map( + (community) => community.id + ); + + expect(idOfJoinedCommunities).toEqual(['communityAlpha']); + expect(unregisteredCommunities).toMatchInlineSnapshot(` + Array [ + Object { + "CA": Object { + "rootCertString": "certString", + "rootKeyString": "keyString", + }, + "id": "communityAlpha", + "name": "alpha", + "onionAddress": "", + "peerList": Array [], + "port": 0, + "privateKey": "", + "registrar": null, + "registrarUrl": "", + "rootCa": "", + }, + ] + `); + }); +}); diff --git a/src/sagas/identity/identity.selectors.ts b/src/sagas/identity/identity.selectors.ts index 956e0f0..2acf787 100644 --- a/src/sagas/identity/identity.selectors.ts +++ b/src/sagas/identity/identity.selectors.ts @@ -2,7 +2,7 @@ import { StoreKeys } from '../store.keys'; import { createSelector } from '@reduxjs/toolkit'; import { identityAdapter } from './identity.adapter'; import { CreatedSelectors, StoreState } from '../store.types'; -import { communitiesSelectors } from '../communities/communities.selectors'; +import { allCommunities, communitiesSelectors, _allCommunities } from '../communities/communities.selectors'; const identitySlice: CreatedSelectors[StoreKeys.Identity] = ( state: StoreState @@ -27,8 +27,50 @@ export const currentIdentity = createSelector( } ); +export const joinedCommunities = createSelector( + allCommunities, + identitySlice, + (allCommunities, reducerState) => { + return allCommunities.filter((community) => { + const identityFromCommunity = identityAdapter + .getSelectors() + .selectById(reducerState.identities, community.id) + return identityFromCommunity && identityFromCommunity.userCertificate + }) + } +); + +export const unregisteredCommunities = createSelector( + allCommunities, + identitySlice, + (allCommunities, reducerState) => { + return allCommunities.filter((community) => { + const identityFromCommunity = identityAdapter + .getSelectors() + .selectById(reducerState.identities, community.id) + return !identityFromCommunity?.userCertificate && identityFromCommunity + }) + } +); + +export const unregisteredCommunitiesWithoutUserIdentity = createSelector( + allCommunities, + identitySlice, + (allCommunities, reducerState) => { + return allCommunities.filter((community) => { + const identityFromCommunity = identityAdapter + .getSelectors() + .selectById(reducerState.identities, community.id) + return !identityFromCommunity + }) + } +); + export const identitySelectors = { selectById, selectEntities, currentIdentity, + joinedCommunities, + unregisteredCommunities, + unregisteredCommunitiesWithoutUserIdentity, }; diff --git a/src/sagas/publicChannels/__snapshots__/publicChannels.selectors.test.ts.snap b/src/sagas/publicChannels/__snapshots__/publicChannels.selectors.test.ts.snap index 3c51148..6e56006 100644 --- a/src/sagas/publicChannels/__snapshots__/publicChannels.selectors.test.ts.snap +++ b/src/sagas/publicChannels/__snapshots__/publicChannels.selectors.test.ts.snap @@ -183,7 +183,7 @@ Object { exports[`publicChannelsSelectors get sliced messages 7`] = ` Object { "channelId": "general", - "createdAt": 1639169400, + "createdAt": 1639687800, "id": "9", "message": "message_9", "pubKey": Any, diff --git a/src/sagas/publicChannels/publicChannels.selectors.test.ts b/src/sagas/publicChannels/publicChannels.selectors.test.ts index f0094b7..00d3bf6 100644 --- a/src/sagas/publicChannels/publicChannels.selectors.test.ts +++ b/src/sagas/publicChannels/publicChannels.selectors.test.ts @@ -224,97 +224,97 @@ describe('publicChannelsSelectors', () => { it('get grouped messages', async () => { const messages = currentChannelMessagesMergedBySender(store.getState()); expect(messages).toMatchInlineSnapshot(` +Object { + "Feb 05": Array [ + Array [ Object { - "Feb 05": Array [ - Array [ - Object { - "createdAt": 1612548120, - "date": "Feb 05, 6:02 PM", - "id": "7", - "message": "message_7", - "nickname": "holmes", - "type": 1, - }, - Object { - "createdAt": 1612558200, - "date": "Feb 05, 8:50 PM", - "id": "8", - "message": "message_8", - "nickname": "holmes", - "type": 1, - }, - ], - ], - "Oct 20": Array [ - Array [ - Object { - "createdAt": 1603173000, - "date": "Oct 20, 5:50 AM", - "id": "1", - "message": "message_1", - "nickname": "holmes", - "type": 1, - }, - Object { - "createdAt": 1603174200, - "date": "Oct 20, 6:10 AM", - "id": "2", - "message": "message_2", - "nickname": "holmes", - "type": 1, - }, - Object { - "createdAt": 1603174290.001, - "date": "Oct 20, 6:11 AM", - "id": "3", - "message": "message_3", - "nickname": "holmes", - "type": 1, - }, - Object { - "createdAt": 1603174290.002, - "date": "Oct 20, 6:11 AM", - "id": "4", - "message": "message_4", - "nickname": "holmes", - "type": 1, - }, - ], - Array [ - Object { - "createdAt": 1603174321, - "date": "Oct 20, 6:12 AM", - "id": "5", - "message": "message_5", - "nickname": "bartek", - "type": 1, - }, - ], - Array [ - Object { - "createdAt": 1603174322, - "date": "Oct 20, 6:12 AM", - "id": "6", - "message": "message_6", - "nickname": "holmes", - "type": 1, - }, - ], - ], - "Today": Array [ - Array [ - Object { - "createdAt": 1639169400, - "date": "8:50 PM", - "id": "9", - "message": "message_9", - "nickname": "holmes", - "type": 1, - }, - ], - ], - } - `); + "createdAt": 1612548120, + "date": "Feb 05, 6:02 PM", + "id": "7", + "message": "message_7", + "nickname": "holmes", + "type": 1, + }, + Object { + "createdAt": 1612558200, + "date": "Feb 05, 8:50 PM", + "id": "8", + "message": "message_8", + "nickname": "holmes", + "type": 1, + }, + ], + ], + "Oct 20": Array [ + Array [ + Object { + "createdAt": 1603173000, + "date": "Oct 20, 5:50 AM", + "id": "1", + "message": "message_1", + "nickname": "holmes", + "type": 1, + }, + Object { + "createdAt": 1603174200, + "date": "Oct 20, 6:10 AM", + "id": "2", + "message": "message_2", + "nickname": "holmes", + "type": 1, + }, + Object { + "createdAt": 1603174290.001, + "date": "Oct 20, 6:11 AM", + "id": "3", + "message": "message_3", + "nickname": "holmes", + "type": 1, + }, + Object { + "createdAt": 1603174290.002, + "date": "Oct 20, 6:11 AM", + "id": "4", + "message": "message_4", + "nickname": "holmes", + "type": 1, + }, + ], + Array [ + Object { + "createdAt": 1603174321, + "date": "Oct 20, 6:12 AM", + "id": "5", + "message": "message_5", + "nickname": "bartek", + "type": 1, + }, + ], + Array [ + Object { + "createdAt": 1603174322, + "date": "Oct 20, 6:12 AM", + "id": "6", + "message": "message_6", + "nickname": "holmes", + "type": 1, + }, + ], + ], + "Today": Array [ + Array [ + Object { + "createdAt": 1639687800, + "date": "8:50 PM", + "id": "9", + "message": "message_9", + "nickname": "holmes", + "type": 1, + }, + ], + ], +} +`); }); });