-
Notifications
You must be signed in to change notification settings - Fork 709
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Manage users in LOD #12228
Open
AlexVelezLl
wants to merge
28
commits into
learningequality:develop
Choose a base branch
from
AlexVelezLl:manage-user-lod
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Manage users in LOD #12228
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
644cf53
Consolidate list remote users api
AlexVelezLl 13f4be0
Remove comment
AlexVelezLl c4d0ab4
Add needed values for BaseValuesViewset
AlexVelezLl 9619363
Add initial structure
AlexVelezLl 289d486
Add remove user
AlexVelezLl edd2025
Separate importLodUsersMachine
AlexVelezLl 478aeca
Clean importLodUsersMachine
AlexVelezLl 0aebe12
Initialize service
AlexVelezLl e8c6d48
Setup users routes
AlexVelezLl 72011fc
Add select facility flow
AlexVelezLl d92d6c9
Fix immersivePage not closing
AlexVelezLl 3264ad9
Add import user With credentials view
AlexVelezLl 66b950e
Completing flow of importing users with credentials
AlexVelezLl 0da59b4
Remove user
AlexVelezLl 1ac99ea
Show loading status
AlexVelezLl 5d41e1a
Add import user as admin flow
AlexVelezLl 523135d
Remove user certificates and morango metadata
AlexVelezLl 2724db4
Track specific user and disable import button on load
AlexVelezLl cff8e5c
Fix add new device flow
AlexVelezLl 3ea25dd
Store machine state
AlexVelezLl 6734ded
Show imported and loading user in import as admin
AlexVelezLl 1d00a7c
Add error handing and success messages
AlexVelezLl 7ce5576
Manage user persmissions to view users management in LOD
AlexVelezLl 4c45c09
Optimize fetching users data
AlexVelezLl fc513ac
Fixes
AlexVelezLl ba36709
Add documentation and tests for importLodUsersMachine
AlexVelezLl b181f0b
misc fixes
AlexVelezLl d854a76
Add edit admin permissions and refactor api resources
AlexVelezLl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,31 @@ | ||
import urls from 'kolibri.urls'; | ||
import client from 'kolibri.client'; | ||
import { Resource } from 'kolibri.lib.apiResource'; | ||
|
||
export default new Resource({ | ||
name: 'facilityuser', | ||
removeImportedUser(user_id) { | ||
return client({ | ||
url: urls['kolibri:core:deleteimporteduser'](), | ||
method: 'POST', | ||
data: { | ||
user_id, | ||
}, | ||
}); | ||
}, | ||
async listRemoteFacilityLearners(params) { | ||
const { data } = await client({ | ||
url: urls['kolibri:core:remotefacilityauthenticateduserinfo'](), | ||
method: 'POST', | ||
data: params, | ||
}); | ||
|
||
const admin = data.find(user => user.username === params.username); | ||
const students = data.filter(user => !user.roles || !user.roles.length); | ||
|
||
return { | ||
admin, | ||
students, | ||
}; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
287 changes: 287 additions & 0 deletions
287
kolibri/core/assets/src/machines/__test__/importLodUsersMachine.spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,287 @@ | ||
import { interpret } from 'xstate'; | ||
import { LodTypePresets } from 'kolibri.coreVue.vuex.constants'; | ||
import { getImportLodUsersMachine } from '../importLodUsersMachine'; | ||
|
||
describe('importLodUsersMachine', () => { | ||
it('should return a machine', () => { | ||
const machine = getImportLodUsersMachine(); | ||
expect(machine).toBeDefined(); | ||
}); | ||
|
||
describe('import single user by auth flow', () => { | ||
const service = interpret(getImportLodUsersMachine()); | ||
service.start(); | ||
|
||
it('Being at the initial state, should be able to set the lod type as import, and the deviceId to import from', () => { | ||
// at selectLodSetupType state | ||
const deviceId = 'test-device-id'; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
importOrJoin: LodTypePresets.IMPORT, | ||
importDeviceId: deviceId, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.lodImportOrJoin).toBe(LodTypePresets.IMPORT); | ||
expect(context.importDeviceId).toBe(deviceId); | ||
expect(state.value).toBe('selectLodFacility'); | ||
}); | ||
|
||
it('Should be able to select a facility to import users from, and set the importDevice and how many facilities there are', () => { | ||
// at selectLodFacility state | ||
const selectedFacility = { id: 'test-facility-id' }; | ||
const importDevice = { id: 'test-device-id' }; | ||
const facilitiesCount = 2; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
selectedFacility, | ||
importDevice, | ||
facilitiesCount, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.selectedFacility).toBe(selectedFacility); | ||
expect(context.importDevice).toBe(importDevice); | ||
expect(context.facilitiesOnDeviceCount).toBe(facilitiesCount); | ||
expect(context.importDeviceId).toBe(importDevice.id); | ||
expect(state.value).toBe('lodImportUserAuth'); | ||
}); | ||
|
||
it('should be able to add user being imported', () => { | ||
// at lodImportUserAuth state | ||
const user = { id: 'test-user-id' }; | ||
|
||
service.send({ | ||
type: 'ADD_USER_BEING_IMPORTED', | ||
value: user, | ||
}); | ||
|
||
const { context } = service.getSnapshot(); | ||
expect(context.usersBeingImported).toEqual([user]); | ||
}); | ||
|
||
it('should continue to the loading state', () => { | ||
// at lodImportUserAuth state | ||
service.send('CONTINUE'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodLoading'); | ||
}); | ||
|
||
it('should be able to import another user', () => { | ||
// at lodLoading state | ||
service.send('IMPORT_ANOTHER'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodImportUserAuth'); | ||
}); | ||
|
||
it('should be able to finish the flow', () => { | ||
// at lodLoading state | ||
service.send('FINISH'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('finish'); | ||
}); | ||
}); | ||
|
||
describe('import users as admin flow', () => { | ||
const service = interpret(getImportLodUsersMachine()); | ||
service.start(); | ||
|
||
it('Being at the initial state, should be able to set the lod type as import, and the deviceId to import from', () => { | ||
// at selectLodSetupType state | ||
const deviceId = 'test-device-id'; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
importOrJoin: LodTypePresets.IMPORT, | ||
importDeviceId: deviceId, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.lodImportOrJoin).toBe(LodTypePresets.IMPORT); | ||
expect(context.importDeviceId).toBe(deviceId); | ||
expect(state.value).toBe('selectLodFacility'); | ||
}); | ||
|
||
it('Should be able to select a facility to import users from, and set the importDevice and how many facilities there are', () => { | ||
// at selectLodFacility state | ||
const selectedFacility = { id: 'test-facility-id' }; | ||
const importDevice = { id: 'test-device-id' }; | ||
const facilitiesCount = 2; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
selectedFacility, | ||
importDevice, | ||
facilitiesCount, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.selectedFacility).toBe(selectedFacility); | ||
expect(context.importDevice).toBe(importDevice); | ||
expect(context.facilitiesOnDeviceCount).toBe(facilitiesCount); | ||
expect(context.importDeviceId).toBe(importDevice.id); | ||
expect(state.value).toBe('lodImportUserAuth'); | ||
}); | ||
|
||
it('should be able to continue as admin and set remote users', () => { | ||
// at lodImportUserAuth state | ||
const remoteUsers = [{ id: 'test-user-id1' }, { id: 'test-user-id2' }]; | ||
const remoteAdmin = { id: 'test-admin-id', username: 'username', password: 'password' }; | ||
|
||
service.send({ | ||
type: 'CONTINUEADMIN', | ||
value: { | ||
users: remoteUsers, | ||
adminUsername: remoteAdmin.username, | ||
adminPassword: remoteAdmin.password, | ||
id: remoteAdmin.id, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.remoteUsers).toEqual(remoteUsers); | ||
expect(context.remoteAdmin).toEqual(remoteAdmin); | ||
expect(state.value).toBe('lodImportAsAdmin'); | ||
}); | ||
|
||
it('should be able to add user being imported', () => { | ||
// at lodImportAsAdmin state | ||
const user = { id: 'test-user-id' }; | ||
|
||
service.send({ | ||
type: 'ADD_USER_BEING_IMPORTED', | ||
value: user, | ||
}); | ||
|
||
const { context } = service.getSnapshot(); | ||
expect(context.usersBeingImported).toEqual([user]); | ||
}); | ||
|
||
it('should be able to go to the loading page', () => { | ||
// at lodImportAsAdmin state | ||
service.send('LOADING'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodLoading'); | ||
}); | ||
|
||
it('should be able to import another user', () => { | ||
// at lodLoading state | ||
service.send('IMPORT_ANOTHER'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodImportUserAuth'); | ||
}); | ||
|
||
it('should be able to finish the flow', () => { | ||
// at lodLoading state | ||
service.send('FINISH'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('finish'); | ||
}); | ||
}); | ||
|
||
describe('Join facility creating a new user flow', () => { | ||
const service = interpret(getImportLodUsersMachine()); | ||
service.start(); | ||
|
||
it('Being at the initial state, should be able to set the lod type as join, and the deviceId to import from', () => { | ||
// at selectLodSetupType state | ||
const deviceId = 'test-device-id'; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
importOrJoin: LodTypePresets.JOIN, | ||
importDeviceId: deviceId, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.lodImportOrJoin).toBe(LodTypePresets.JOIN); | ||
expect(context.importDeviceId).toBe(deviceId); | ||
expect(state.value).toBe('selectLodFacility'); | ||
}); | ||
|
||
it('Should be able to select a facility to import users from, and set the importDevice and how many facilities there are', () => { | ||
// at selectLodFacility state | ||
const selectedFacility = { id: 'test-facility-id' }; | ||
const importDevice = { id: 'test-device-id' }; | ||
const facilitiesCount = 2; | ||
|
||
service.send({ | ||
type: 'CONTINUE', | ||
value: { | ||
selectedFacility, | ||
importDevice, | ||
facilitiesCount, | ||
}, | ||
}); | ||
|
||
const state = service.getSnapshot(); | ||
const { context } = state; | ||
expect(context.selectedFacility).toBe(selectedFacility); | ||
expect(context.importDevice).toBe(importDevice); | ||
expect(context.facilitiesOnDeviceCount).toBe(facilitiesCount); | ||
expect(context.importDeviceId).toBe(importDevice.id); | ||
expect(state.value).toBe('lodJoinFacility'); | ||
}); | ||
|
||
it('should be able to add user being imported', () => { | ||
// at lodJoinFacility state | ||
const user = { id: 'test-user-id' }; | ||
|
||
service.send({ | ||
type: 'ADD_USER_BEING_IMPORTED', | ||
value: user, | ||
}); | ||
|
||
const { context } = service.getSnapshot(); | ||
expect(context.usersBeingImported).toEqual([user]); | ||
}); | ||
|
||
it('should continue to the loading state', () => { | ||
// at lodJoinFacility state | ||
service.send('CONTINUE'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodJoinLoading'); | ||
}); | ||
|
||
it('should be able to import another user', () => { | ||
// at lodJoinLoading state | ||
service.send('IMPORT_ANOTHER'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('lodImportUserAuth'); | ||
}); | ||
|
||
it('should be able to finish the flow', () => { | ||
// at lodJoinLoading state | ||
service.send('FINISH'); | ||
|
||
const state = service.getSnapshot(); | ||
expect(state.value).toBe('finish'); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd rather put this in
kolibri-common
rather than add it to the core API spec.