Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions kolibri/plugins/setup_wizard/frontend/__tests__/api.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import client from 'kolibri/client';
import { SetupWizardResource, FacilityImportResource } from '../api';

jest.mock('kolibri/client');
// Not the shared urls mock: it resolves every name to the same string, so a wrong `action`
// would pass.
jest.mock('kolibri/urls', () => ({
__esModule: true,
default: new Proxy({}, { get: (target, name) => () => name }),
}));

describe('setup_wizard resources', () => {
beforeEach(() => {
client.__reset();
});

it('posts a remote user creation and resolves the response body', async () => {
client.__setPayload({ status: 201, errors: [] });
const user = {
facility_id: 'facility_1',
username: 'learner',
password: 'password',
full_name: 'A Learner',
baseurl: 'http://kolibri.remote',
};
const result = await SetupWizardResource.createuseronremote(user);
expect(client.mock.calls[0][0]).toMatchObject({
method: 'POST',
url: expect.stringMatching(/setupwizard_createuseronremote$/),
data: user,
});
expect(result).toEqual({ status: 201, errors: [] });
});

it('gets the facility admins and resolves the list', async () => {
client.__setPayload([{ id: 'admin_1', username: 'admin' }]);
const result = await FacilityImportResource.facilityadmins();
expect(client.mock.calls[0][0]).toMatchObject({
method: 'GET',
url: expect.stringMatching(/facilityimport_facilityadmins$/),
});
expect(result).toEqual([{ id: 'admin_1', username: 'admin' }]);
});

it('posts the superuser grant as a body', async () => {
await FacilityImportResource.grantsuperuserpermissions({
user_id: 'user_1',
password: 'password',
});
expect(client.mock.calls[0][0]).toMatchObject({
method: 'POST',
url: expect.stringMatching(/facilityimport_grantsuperuserpermissions$/),
data: { user_id: 'user_1', password: 'password' },
});
});

it('posts the new superuser as a body', async () => {
const superuser = {
username: 'admin',
full_name: 'An Admin',
password: 'password',
extra_fields: {},
facility_name: 'Kolibri School',
};
await FacilityImportResource.createsuperuser(superuser);
expect(client.mock.calls[0][0]).toMatchObject({
method: 'POST',
url: expect.stringMatching(/facilityimport_createsuperuser$/),
data: superuser,
});
});
});
57 changes: 21 additions & 36 deletions kolibri/plugins/setup_wizard/frontend/api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import client from 'kolibri/client';
import urls from 'kolibri/urls';
import { Resource } from 'kolibri/apiResource';

/**
Expand All @@ -12,50 +10,37 @@ export const SetupWizardResource = new Resource({
name: 'setupwizard',
namespace: 'kolibri.plugins.setup_wizard',

createuseronremote({ facility_id, username, password, full_name, baseurl }) {
return this.postListEndpoint('createuseronremote', {
facility_id,
username,
password,
full_name,
baseurl,
async createuseronremote({ facility_id, username, password, full_name, baseurl }) {
const response = await this.request({
method: 'POST',
action: 'createuseronremote',
data: { facility_id, username, password, full_name, baseurl },
});
return response.data;
},
});

export const FacilityImportResource = new Resource({
name: 'facilityimport',
namespace: 'kolibri.plugins.setup_wizard',
grantsuperuserpermissions({ user_id, password }) {
return this.postListEndpoint('grantsuperuserpermissions', { user_id, password });
},
createsuperuser({ username, full_name, password, extra_fields, facility_name }) {
return this.postListEndpoint('createsuperuser', {
username,
full_name,
password,
extra_fields,
facility_name,
});
},
facilityadmins() {
return this.getListEndpoint('facilityadmins').then(response => {
return response.data;
async grantsuperuserpermissions({ user_id, password }) {
const response = await this.request({
method: 'POST',
action: 'grantsuperuserpermissions',
data: { user_id, password },
});
return response.data;
},
async listfacilitylearners(params) {
const { data } = await client({
url: urls['kolibri:core:remotefacilityauthenticateduserinfo'](),
async createsuperuser({ username, full_name, password, extra_fields, facility_name }) {
const response = await this.request({
method: 'POST',
data: params,
action: 'createsuperuser',
data: { username, full_name, password, extra_fields, facility_name },
});

const admin = data.find(user => user.username === params.username);
const students = data.filter(user => !user.roles || !user.roles.length);

return {
admin,
students,
};
return response.data;
},
async facilityadmins() {
const response = await this.request({ action: 'facilityadmins' });
return response.data;
},
});
2 changes: 1 addition & 1 deletion kolibri/plugins/setup_wizard/frontend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class SetupWizardModule extends KolibriApp {
// Don't call beat because it may cause a save in the session endpoint
// while the device provisioning is in progress
logging.info('Clearing facility tasks created in previous sessions...');
TaskResource.clearAll('facility_task');
TaskResource.clearAll_v2('facility_task');
this.startRootVue();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@
});
if (isFailingTasks) {
this.createSnackbar(this.importUserError$());
TaskResource.clearAll(SoudQueue);
TaskResource.clearAll_v2(SoudQueue);
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,12 +211,12 @@
});
},
retryImport() {
TaskResource.restart(this.loadingTask.id).catch(error => {
TaskResource.restart_v2(this.loadingTask.id).catch(error => {
this.handleApiError({ error });
});
},
cancelTask() {
return TaskResource.cancel(this.loadingTask.id);
return TaskResource.cancel_v2(this.loadingTask.id);
},
startOver() {
this.isPolling = false;
Expand All @@ -225,7 +225,7 @@
});
},
clearTasks() {
return TaskResource.clearAll(this.queue);
return TaskResource.clearAll_v2(this.queue);
},
handleClickContinue() {
this.isPolling = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@
facility_id: this.facility.id,
baseurl: baseurl.slice(0, -1),
...user,
}).then(response => {
const { status, errors } = response.data;

}).then(({ status, errors }) => {
if (status == 201) {
const task_name = 'kolibri.core.auth.tasks.peeruserimport';
const params = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const { continueAction$, retryAction$, startOverAction$, cancelAction$ } = coreS
const { importFacilityAction$ } = syncStrings;

jest.mock('kolibri/apiResources/TaskResource', () => ({
cancel: jest.fn().mockResolvedValue({}),
clearAll: jest.fn().mockResolvedValue({}),
restart: jest.fn().mockResolvedValue({}),
cancel_v2: jest.fn().mockResolvedValue({}),
clearAll_v2: jest.fn().mockResolvedValue({}),
restart_v2: jest.fn().mockResolvedValue({}),
list: jest.fn().mockResolvedValue([]),
}));

Expand Down Expand Up @@ -134,7 +134,7 @@ describe('LoadingTaskPage', () => {
await userEvent.click(continueButton);

expect(sendMock).toHaveBeenCalledWith('CONTINUE');
expect(TaskResource.clearAll).toHaveBeenCalledTimes(1);
expect(TaskResource.clearAll_v2).toHaveBeenCalledTimes(1);
});

it('when task fails, the "retry" button is available', async () => {
Expand All @@ -148,7 +148,7 @@ describe('LoadingTaskPage', () => {

await userEvent.click(retryButton);

expect(TaskResource.restart).toHaveBeenCalledTimes(1);
expect(TaskResource.restart_v2).toHaveBeenCalledTimes(1);
});

it('when task fails, the "start over" button is available', async () => {
Expand All @@ -164,7 +164,7 @@ describe('LoadingTaskPage', () => {

await userEvent.click(startOverButton);

expect(TaskResource.clearAll).toHaveBeenCalledTimes(1);
expect(TaskResource.clearAll_v2).toHaveBeenCalledTimes(1);
});

it('a cancel request is made when "cancel" is clicked', async () => {
Expand All @@ -177,7 +177,7 @@ describe('LoadingTaskPage', () => {
await fireEvent.click(cancelButton);

await waitFor(() => {
expect(TaskResource.cancel).toHaveBeenCalledTimes(1);
expect(TaskResource.cancel_v2).toHaveBeenCalledTimes(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@
Lockr.rm('savedState'); // Clear out saved state machine
},
clearPollingTasks() {
TaskResource.clearAll(PROVISION_TASK_QUEUE);
TaskResource.clearAll_v2(PROVISION_TASK_QUEUE);
},
},
$trs: {
Expand Down
Loading