From c7ed63b153b978fca20888002f0df818e6b4c0a0 Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Fri, 10 Aug 2018 15:23:46 +0100 Subject: [PATCH 1/7] Kind of working --- aimmo/views.py | 3 +- game_frontend/src/redux/api/socket.js | 4 +- .../src/redux/features/Game/actions.js | 26 ++++++++++++- .../src/redux/features/Game/epics.js | 38 ++++++++++++++----- .../src/redux/features/Game/types.js | 8 ++++ 5 files changed, 65 insertions(+), 14 deletions(-) diff --git a/aimmo/views.py b/aimmo/views.py index afd14791d..6f5a6c469 100644 --- a/aimmo/views.py +++ b/aimmo/views.py @@ -116,8 +116,9 @@ def connection_parameters(request, game_id): LOGGER.error(e) return HttpResponse('Unknown error occurred when getting the current avatar', status=500) - env_connection_settings.update({'avatar_id': avatar_id}) + print "INSIDE CONNECTION PARAMETERS" + print env_connection_settings return JsonResponse(env_connection_settings) diff --git a/game_frontend/src/redux/api/socket.js b/game_frontend/src/redux/api/socket.js index ae7e53d86..bf39fac4a 100644 --- a/game_frontend/src/redux/api/socket.js +++ b/game_frontend/src/redux/api/socket.js @@ -6,8 +6,8 @@ import { fromEvent } from 'rxjs/observable/fromEvent' import { pipe } from 'rxjs/Rx' const connectToGame = () => - map(response => { - const { game_url_base: gameUrlBase, game_url_path: gameUrlPath, avatar_id: avatarId } = response + map(action => { + const { game_url_base: gameUrlBase, game_url_path: gameUrlPath, avatar_id: avatarId } = action.payload.parameters return io(gameUrlBase, { path: gameUrlPath, query: { diff --git a/game_frontend/src/redux/features/Game/actions.js b/game_frontend/src/redux/features/Game/actions.js index 7deb08442..99d940178 100644 --- a/game_frontend/src/redux/features/Game/actions.js +++ b/game_frontend/src/redux/features/Game/actions.js @@ -42,10 +42,34 @@ const unityEvent = (unityEvent, unityData, successAction, failAction) => ( } ) +const connectionParametersReceived = parameters => ( + { + type: types.CONNECTION_PARAMETERS_RECEIVED, + payload: { + parameters + } + } +) + +const avatarIdSet = () => ( + { + type: types.AVATAR_ID_SET + } +) + +const avatarIdFailed = () => ( + { + type: types.AVATAR_ID_FAILED + } +) + export default { socketConnectToGameRequest, sendGameStateFail, sendGameStateSuccess, socketGameStateReceived, - unityEvent + unityEvent, + connectionParametersReceived, + avatarIdSet, + avatarIdFailed } diff --git a/game_frontend/src/redux/features/Game/epics.js b/game_frontend/src/redux/features/Game/epics.js index d4626e82a..c8070a175 100644 --- a/game_frontend/src/redux/features/Game/epics.js +++ b/game_frontend/src/redux/features/Game/epics.js @@ -1,20 +1,14 @@ import actions from './actions' import types from './types' import { Observable } from 'rxjs' -import { map, mergeMap, catchError } from 'rxjs/operators' +import { map, mergeMap, catchError, delay, tap } from 'rxjs/operators' import { ofType } from 'redux-observable' -const connectToGameEpic = (action$, store, { api: { get, socket } }) => action$.pipe( +const getConnectionParametersEpic = (action$, store, { api: { get } }) => action$.pipe( ofType(types.SOCKET_CONNECT_TO_GAME_REQUEST), mergeMap(action => get(`games/${store.getState().game.connectionParameters.id}/connection_parameters/`).pipe( - socket.connectToGame(), - socket.startListeners(), - catchError(error => Observable.of({ - type: types.SOCKET_CONNECT_TO_GAME_FAIL, - payload: error, - error: true - })) + map(response => actions.connectionParametersReceived(response)) ) ) ) @@ -30,7 +24,31 @@ const sendGameStateEpic = (action$, store, { api: { unity } }) => action$.pipe( unity.sendExternalEvent(unity.emitToUnity) ) +const connectToGameEpic = (action$, store, { api: { socket, unity } }) => action$.pipe( + ofType(types.CONNECTION_PARAMETERS_RECEIVED), + socket.connectToGame(), + socket.startListeners(), + catchError(error => Observable.of({ + type: types.SOCKET_CONNECT_TO_GAME_FAIL, + payload: error, + error: true + })) +) + +const sendAvatarIDEpic = (action$, store, { api: { unity } }) => action$.pipe( + ofType(types.CONNECTION_PARAMETERS_RECEIVED), + map(action => actions.unityEvent( + 'SetCurrentAvatarID', + parseInt(action.payload.parameters['avatar_id']), + actions.avatarIdSet(), + actions.avatarIdFailed + )), + unity.sendExternalEvent(unity.emitToUnity) +) + export default { + getConnectionParametersEpic, connectToGameEpic, - sendGameStateEpic + sendGameStateEpic, + sendAvatarIDEpic } diff --git a/game_frontend/src/redux/features/Game/types.js b/game_frontend/src/redux/features/Game/types.js index efc728413..bd9912701 100644 --- a/game_frontend/src/redux/features/Game/types.js +++ b/game_frontend/src/redux/features/Game/types.js @@ -7,6 +7,11 @@ const SEND_GAME_STATE_FAIL = 'features/Game/SOCKET_GAME_STATE_UPDATE_FAIL' const UNITY_EVENT = 'features/Game/UNITY_EVENT' // check naming +const CONNECTION_PARAMETERS_RECEIVED = 'features/GAME/CONNECTION_PARAMTERS_RECEIVED' + +const AVATAR_ID_SET = 'features/GAME/AVATAR_ID_SET' +const AVATAR_ID_FAILED = 'features/GAME/AVATAR_ID_FAILED' + export default { SOCKET_CONNECT_TO_GAME_REQUEST, SOCKET_CONNECT_TO_GAME_FAIL, @@ -14,4 +19,7 @@ export default { SEND_GAME_STATE_SUCCESS, SEND_GAME_STATE_FAIL, UNITY_EVENT, + CONNECTION_PARAMETERS_RECEIVED, + AVATAR_ID_SET, + AVATAR_ID_FAILED } From 900a0ba431d6e3989182579ffd70ace4c1b38d83 Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 11:44:55 +0100 Subject: [PATCH 2/7] Finished writing all the tests --- game_frontend/src/index.js | 6 +- .../src/redux/features/Game/epics.js | 2 +- .../src/redux/features/Game/epics.test.js | 193 ++++++++++++------ 3 files changed, 136 insertions(+), 65 deletions(-) diff --git a/game_frontend/src/index.js b/game_frontend/src/index.js index a992e2099..bc5d8216b 100644 --- a/game_frontend/src/index.js +++ b/game_frontend/src/index.js @@ -27,11 +27,7 @@ const initialState = { }, game: { connectionParameters: { - id: getGameIDFromURL() || 1, - game_url_base: '', - game_url_path: '', - game_url_port: 0, - game_ssl_flag: false + game_id: getGameIDFromURL() || 1 } } } diff --git a/game_frontend/src/redux/features/Game/epics.js b/game_frontend/src/redux/features/Game/epics.js index c8070a175..51e643785 100644 --- a/game_frontend/src/redux/features/Game/epics.js +++ b/game_frontend/src/redux/features/Game/epics.js @@ -7,7 +7,7 @@ import { ofType } from 'redux-observable' const getConnectionParametersEpic = (action$, store, { api: { get } }) => action$.pipe( ofType(types.SOCKET_CONNECT_TO_GAME_REQUEST), mergeMap(action => - get(`games/${store.getState().game.connectionParameters.id}/connection_parameters/`).pipe( + get(`games/${store.getState().game.connectionParameters.game_id}/connection_parameters/`).pipe( map(response => actions.connectionParametersReceived(response)) ) ) diff --git a/game_frontend/src/redux/features/Game/epics.test.js b/game_frontend/src/redux/features/Game/epics.test.js index 4f9f69196..3289ce2d9 100644 --- a/game_frontend/src/redux/features/Game/epics.test.js +++ b/game_frontend/src/redux/features/Game/epics.test.js @@ -19,65 +19,6 @@ const createTestScheduler = (frameTimeFactor = 10) => { return new TestScheduler(deepEquals) } -describe('connectToGameEpic', () => { - it('connects to the aimmo-game', () => { - const gameState = { - players: { - id: 1, - location: { - x: 10, - y: 10 - } - } - } - - const marbles1 = '-a---' - const marbles2 = '--b--' - const values = { - a: actions.socketConnectToGameRequest(), - b: actions.socketGameStateReceived(gameState) - } - - const testScheduler = createTestScheduler() - const source$ = ActionsObservable.from( - testScheduler.createColdObservable(marbles1, values) - ) - const mockGetJSON = () => - Observable.of({ id: 1 }) - - const mockConnectToGame = () => - mapTo({type: 'socket'}) - - const mockStartListeners = () => - pipe( - delay(10, testScheduler), - mapTo(actions.socketGameStateReceived(gameState)) - ) - - const mockAPI = { - api: { - get: mockGetJSON, - socket: { - connectToGame: mockConnectToGame, - startListeners: mockStartListeners - } - } - } - - const actual = epics.connectToGameEpic(source$, mockStore({ - game: { - connectionParameters: - { - id: 1 - } - } - }), mockAPI) - - testScheduler.expectObservable(actual).toBe(marbles2, values) - testScheduler.flush() - }) -}) - describe('ReceiveGameUpdate', () => { it('sends game update', () => { const gameState = { @@ -174,3 +115,137 @@ describe('ReceiveGameUpdate', () => { testScheduler.flush() }) }) + +describe('sendAvatarIDEpic', () => { + it('sends avatar id', () => { + const parameters = { + avatar_id: 1 + } + const marbles1 = '-a--' + const marbles2 = '-b--' + const values = { + a: actions.connectionParametersReceived(parameters), + b: actions.avatarIdSet() + } + + const testScheduler = createTestScheduler() + const source$ = ActionsObservable.from( + testScheduler.createColdObservable(marbles1, values) + ) + + const mockEmitToUnity = () => { + return Observable.of(values.b) + } + + const mockAPI = { + api: { + unity: { + ...api.unity, + emitToUnity: mockEmitToUnity + + } + } + } + + const actual = epics.sendAvatarIDEpic(source$, mockStore({}), mockAPI) + + testScheduler.expectObservable(actual).toBe(marbles2, values) + testScheduler.flush() + }) +}) + +// rewriting connect to game epic test + +describe('connectToGameEpic', () => { + it('connects to the aimmo game', () => { + const gameState = { + players: { + id: 1, + location: { + x: 10, + y: 10 + } + } + } + + const parameters = { + avatar_id: 1 + } + + const marbles1 = '-a---' + const marbles2 = '--b--' + const values = { + a: actions.connectionParametersReceived(parameters), + b: actions.socketGameStateReceived(gameState) + } + + const testScheduler = createTestScheduler() + const source$ = ActionsObservable.from( + testScheduler.createColdObservable(marbles1, values) + ) + + const mockConnectToGame = () => + mapTo({type: 'socket'}) + + const mockStartListeners = () => + pipe( + delay(10, testScheduler), + mapTo(actions.socketGameStateReceived(gameState)) + ) + + const mockAPI = { + api: { + socket: { + connectToGame: mockConnectToGame, + startListeners: mockStartListeners + } + } + } + + const actual = epics.connectToGameEpic(source$, mockStore({}), mockAPI) + + testScheduler.expectObservable(actual).toBe(marbles2, values) + testScheduler.flush() + }) +}) + +describe('getConnectionParametersEpic', () => { + it('gets all the connection parameters', () => { + const parameters = { + avatar_id: 1 + } + + const marbles1 = '-a--' + const marbles2 = '-b--' + const values = { + a: actions.socketConnectToGameRequest(), + b: actions.connectionParametersReceived(parameters) + } + + const testScheduler = createTestScheduler() + const source$ = ActionsObservable.from( + testScheduler.createColdObservable(marbles1, values) + ) + + const mockGetJSON = () => + Observable.of({ avatar_id: 1 }) + + const mockAPI = { + api: { + get: mockGetJSON + } + } + + const actual = epics.getConnectionParametersEpic(source$, mockStore({ + game: { + connectionParameters: { + // game_id + game_id: 1 + } + } + }), mockAPI) + + testScheduler.expectObservable(actual).toBe(marbles2, values) + testScheduler.flush() + }) +}) From 7598038d94ab6a2b78b201232e8c9e1a3ed24555 Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 11:47:30 +0100 Subject: [PATCH 3/7] Removed prints --- aimmo/views.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/aimmo/views.py b/aimmo/views.py index 6f5a6c469..b072054df 100644 --- a/aimmo/views.py +++ b/aimmo/views.py @@ -117,8 +117,6 @@ def connection_parameters(request, game_id): return HttpResponse('Unknown error occurred when getting the current avatar', status=500) env_connection_settings.update({'avatar_id': avatar_id}) - print "INSIDE CONNECTION PARAMETERS" - print env_connection_settings return JsonResponse(env_connection_settings) From 6548a236b7046f46ba517276d46c2709ed6c1996 Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 13:09:30 +0100 Subject: [PATCH 4/7] Renamed avatar id actions --- game_frontend/src/redux/features/Game/actions.js | 12 ++++++------ game_frontend/src/redux/features/Game/epics.js | 4 ++-- game_frontend/src/redux/features/Game/epics.test.js | 2 +- game_frontend/src/redux/features/Game/types.js | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/game_frontend/src/redux/features/Game/actions.js b/game_frontend/src/redux/features/Game/actions.js index 99d940178..b4a95aa6c 100644 --- a/game_frontend/src/redux/features/Game/actions.js +++ b/game_frontend/src/redux/features/Game/actions.js @@ -51,15 +51,15 @@ const connectionParametersReceived = parameters => ( } ) -const avatarIdSet = () => ( +const unitySendAvatarIDSuccess = () => ( { - type: types.AVATAR_ID_SET + type: types.UNITY_SEND_AVATAR_ID_SUCCESS } ) -const avatarIdFailed = () => ( +const unitySendAvatarIDFail = () => ( { - type: types.AVATAR_ID_FAILED + type: types.UNITY_SEND_AVATAR_ID_FAIL } ) @@ -70,6 +70,6 @@ export default { socketGameStateReceived, unityEvent, connectionParametersReceived, - avatarIdSet, - avatarIdFailed + unitySendAvatarIDSuccess, + unitySendAvatarIDFail } diff --git a/game_frontend/src/redux/features/Game/epics.js b/game_frontend/src/redux/features/Game/epics.js index 51e643785..e77380933 100644 --- a/game_frontend/src/redux/features/Game/epics.js +++ b/game_frontend/src/redux/features/Game/epics.js @@ -40,8 +40,8 @@ const sendAvatarIDEpic = (action$, store, { api: { unity } }) => action$.pipe( map(action => actions.unityEvent( 'SetCurrentAvatarID', parseInt(action.payload.parameters['avatar_id']), - actions.avatarIdSet(), - actions.avatarIdFailed + actions.unitySendAvatarIDSuccess(), + actions.unitySendAvatarIDFail )), unity.sendExternalEvent(unity.emitToUnity) ) diff --git a/game_frontend/src/redux/features/Game/epics.test.js b/game_frontend/src/redux/features/Game/epics.test.js index 3289ce2d9..91398c1dc 100644 --- a/game_frontend/src/redux/features/Game/epics.test.js +++ b/game_frontend/src/redux/features/Game/epics.test.js @@ -125,7 +125,7 @@ describe('sendAvatarIDEpic', () => { const marbles2 = '-b--' const values = { a: actions.connectionParametersReceived(parameters), - b: actions.avatarIdSet() + b: actions.unitySendAvatarIDSuccess() } const testScheduler = createTestScheduler() diff --git a/game_frontend/src/redux/features/Game/types.js b/game_frontend/src/redux/features/Game/types.js index bd9912701..048b3f67b 100644 --- a/game_frontend/src/redux/features/Game/types.js +++ b/game_frontend/src/redux/features/Game/types.js @@ -9,8 +9,8 @@ const UNITY_EVENT = 'features/Game/UNITY_EVENT' // check naming const CONNECTION_PARAMETERS_RECEIVED = 'features/GAME/CONNECTION_PARAMTERS_RECEIVED' -const AVATAR_ID_SET = 'features/GAME/AVATAR_ID_SET' -const AVATAR_ID_FAILED = 'features/GAME/AVATAR_ID_FAILED' +const UNITY_SEND_AVATAR_ID_SUCCESS = 'features/GAME/UNITY_SEND_AVATAR_ID_SUCCESS' +const UNITY_SEND_AVATAR_ID_FAIL = 'features/GAME/UNITY_SEND_AVATAR_ID_FAIL' export default { SOCKET_CONNECT_TO_GAME_REQUEST, @@ -20,6 +20,6 @@ export default { SEND_GAME_STATE_FAIL, UNITY_EVENT, CONNECTION_PARAMETERS_RECEIVED, - AVATAR_ID_SET, - AVATAR_ID_FAILED + UNITY_SEND_AVATAR_ID_SUCCESS, + UNITY_SEND_AVATAR_ID_FAIL } From 682ba099ae773b129b4793d14e45e0b2a6f5902d Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 13:10:30 +0100 Subject: [PATCH 5/7] Removed comments --- game_frontend/src/redux/features/Game/epics.test.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/game_frontend/src/redux/features/Game/epics.test.js b/game_frontend/src/redux/features/Game/epics.test.js index 91398c1dc..5c655d9b2 100644 --- a/game_frontend/src/redux/features/Game/epics.test.js +++ b/game_frontend/src/redux/features/Game/epics.test.js @@ -154,8 +154,6 @@ describe('sendAvatarIDEpic', () => { }) }) -// rewriting connect to game epic test - describe('connectToGameEpic', () => { it('connects to the aimmo game', () => { const gameState = { @@ -239,7 +237,6 @@ describe('getConnectionParametersEpic', () => { const actual = epics.getConnectionParametersEpic(source$, mockStore({ game: { connectionParameters: { - // game_id game_id: 1 } } From 0fd73678fe5c93c78e31a4a973e4081ac15523fd Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 13:30:01 +0100 Subject: [PATCH 6/7] Fixed an error --- game_frontend/src/redux/features/Editor/epics.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/game_frontend/src/redux/features/Editor/epics.js b/game_frontend/src/redux/features/Editor/epics.js index 13f1aacf6..0fdb17792 100644 --- a/game_frontend/src/redux/features/Editor/epics.js +++ b/game_frontend/src/redux/features/Editor/epics.js @@ -10,7 +10,7 @@ const getCodeEpic = (action$, store, { api }) => action$.pipe( ofType(types.GET_CODE_REQUEST), mergeMap(action => - api.get(`code/${store.getState().game.connectionParameters.id}/`).pipe( + api.get(`code/${store.getState().game.connectionParameters.game_id}/`).pipe( map(response => actions.getCodeReceived(response.code)), catchError(error => Observable.of({ type: types.GET_CODE_FAILURE, @@ -26,7 +26,7 @@ const postCodeEpic = (action$, store, { api }) => .pipe( ofType(types.POST_CODE_REQUEST), api.post( - `/aimmo/api/code/${store.getState().game.connectionParameters.id}/`, + `/aimmo/api/code/${store.getState().game.connectionParameters.game_id}/`, () => ({ code: store.getState().editor.code }) ), map(response => actions.postCodeReceived()), From 2fdfc71d6db28020120ec8746cc2047486a2825b Mon Sep 17 00:00:00 2001 From: Ria Jha Date: Mon, 13 Aug 2018 13:50:14 +0100 Subject: [PATCH 7/7] There was a spelling error --- game_frontend/src/redux/features/Game/types.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/game_frontend/src/redux/features/Game/types.js b/game_frontend/src/redux/features/Game/types.js index 048b3f67b..18522fa0d 100644 --- a/game_frontend/src/redux/features/Game/types.js +++ b/game_frontend/src/redux/features/Game/types.js @@ -7,7 +7,7 @@ const SEND_GAME_STATE_FAIL = 'features/Game/SOCKET_GAME_STATE_UPDATE_FAIL' const UNITY_EVENT = 'features/Game/UNITY_EVENT' // check naming -const CONNECTION_PARAMETERS_RECEIVED = 'features/GAME/CONNECTION_PARAMTERS_RECEIVED' +const CONNECTION_PARAMETERS_RECEIVED = 'features/GAME/CONNECTION_PARAMETERS_RECEIVED' const UNITY_SEND_AVATAR_ID_SUCCESS = 'features/GAME/UNITY_SEND_AVATAR_ID_SUCCESS' const UNITY_SEND_AVATAR_ID_FAIL = 'features/GAME/UNITY_SEND_AVATAR_ID_FAIL'