Skip to content

Commit

Permalink
Fix questions handling (#1189)
Browse files Browse the repository at this point in the history
* Fix handling of non-generic questions.
* Fix questions test suite.
  • Loading branch information
imobachgs authored May 10, 2024
2 parents 6534030 + b01a640 commit 5e996aa
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 87 deletions.
10 changes: 4 additions & 6 deletions web/src/client/questions.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function buildQuestion(httpQuestion) {

if (httpQuestion.withPassword) {
question.type = QUESTION_TYPES.withPassword;
question.password = httpQuestion.withPassword.Password;
question.password = httpQuestion.withPassword.password;
}

return question;
Expand Down Expand Up @@ -74,7 +74,7 @@ class QuestionsClient {
async getQuestions() {
const response = await this.client.get("/questions");
if (!response.ok) {
console.log("Failed to get questions: ", response);
console.warn("Failed to get questions: ", response);
return [];
}
const questions = await response.json();
Expand All @@ -87,11 +87,9 @@ class QuestionsClient {
* @param {Object} question
*/
answer(question) {
let answer;
const answer = { generic: { answer: question.answer } };
if (question.type === QUESTION_TYPES.withPassword) {
answer = { withPassword: { password: question.password } };
} else {
answer = { generic: { answer: question.answer } };
answer.withPassword = { password: question.password };
}

const path = `/questions/${question.id}/answer`;
Expand Down
135 changes: 54 additions & 81 deletions web/src/client/questions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,72 +19,30 @@
* find current contact information at www.suse.com.
*/

import DBusClient from "./dbus";
import { HTTPClient } from "./http";
import { QuestionsClient } from "./questions";

jest.mock("./dbus");

// NOTE: should we export them?
const GENERIC_IFACE = "org.opensuse.Agama1.Questions.Generic";
const WITH_PASSWORD_IFACE = "org.opensuse.Agama1.Questions.WithPassword";

const questionProxy = {
wait: jest.fn(),
Answer: ""
};

const withPasswordProxy = {
wait: jest.fn(),
Password: ""
};
const mockJsonFn = jest.fn();
const mockGetFn = jest.fn().mockImplementation(() => {
return { ok: true, json: mockJsonFn };
});
const mockPutFn = jest.fn().mockImplementation(() => {
return { ok: true };
});

const questionPath = "/org/opensuse/Agama1/Questions/432";
const ifacesAndProperties = {
"org.freedesktop.DBus.Properties": {},
"org.opensuse.Agama1.Questions.Generic": {
Id: {
t: "u",
v: 432
},
Class: {
t: "s",
v: "storage.luks_activation"
},
Text: {
t: "s",
v: "The device /dev/vdb1 (2.00 GiB) is encrypted. Do you want to decrypt it?"
},
Options: {
t: "as",
v: [
"skip",
"decrypt"
]
},
DefaultOption: {
t: "s",
v: "decrypt"
},
Data: {
t: "a{ss}",
v: { Attempt: "1" }
},
Answer: {
t: "s",
v: ""
}
},
"org.opensuse.Agama1.Questions.WithPassword": {
Password: {
t: "s",
v: ""
},
}
};
jest.mock("./http", () => {
return {
HTTPClient: jest.fn().mockImplementation(() => {
return {
get: mockGetFn,
put: mockPutFn,
onEvent: jest.fn(),
};
}),
};
});

const getManagedObjectsMock = [
{ [questionPath]: ifacesAndProperties }
];
let client;

const expectedQuestions = [
{
Expand All @@ -97,27 +55,31 @@ const expectedQuestions = [
answer: "",
data: { Attempt: "1" },
password: "",
}
},
];

const proxies = {
[GENERIC_IFACE]: questionProxy,
[WITH_PASSWORD_IFACE]: withPasswordProxy
const luksQuestion = {
generic: {
id: 432,
class: "storage.luks_activation",
text: "The device /dev/vdb1 (2.00 GiB) is encrypted. Do you want to decrypt it?",
options: ["skip", "decrypt"],
defaultOption: "decrypt",
data: { Attempt: "1" },
answer: "",
},
withPassword: { password: "" },
};

beforeEach(() => {
DBusClient.mockImplementation(() => {
return {
proxy: (iface) => proxies[iface],
call: () => getManagedObjectsMock
};
describe("#getQuestions", () => {
beforeEach(() => {
mockJsonFn.mockResolvedValue([luksQuestion]);
client = new QuestionsClient(new HTTPClient(new URL("http://localhost")));
});
});

describe("#getQuestions", () => {
it("returns pending questions", async () => {
const client = new QuestionsClient();
const questions = await client.getQuestions();
expect(mockGetFn).toHaveBeenCalledWith("/questions");
expect(questions).toEqual(expectedQuestions);
});
});
Expand All @@ -126,26 +88,37 @@ describe("#answer", () => {
let question;

beforeEach(() => {
question = { id: 321, type: 'whatever', answer: 'the-answer' };
question = { id: 321, type: "whatever", answer: "the-answer" };
});

it("sets given answer", async () => {
const client = new QuestionsClient();
client = new QuestionsClient(new HTTPClient(new URL("http://localhost")));
await client.answer(question);

expect(questionProxy).toMatchObject({ Answer: 'the-answer' });
expect(mockPutFn).toHaveBeenCalledWith("/questions/321/answer", {
generic: { answer: "the-answer" },
});
});

describe("when answering a question implementing the LUKS activation interface", () => {
beforeEach(() => {
question = { id: 432, type: 'withPassword', class: 'storage.luks_activation', answer: 'skip', password: 'notSecret' };
question = {
id: 432,
type: "withPassword",
class: "storage.luks_activation",
answer: "decrypt",
password: "notSecret",
};
});

it("sets given password", async () => {
const client = new QuestionsClient();
client = new QuestionsClient(new HTTPClient(new URL("http://localhost")));
await client.answer(question);

expect(withPasswordProxy).toMatchObject({ Password: "notSecret" });
expect(mockPutFn).toHaveBeenCalledWith("/questions/432/answer", {
generic: { answer: "decrypt" },
withPassword: { password: "notSecret" },
});
});
});
});

0 comments on commit 5e996aa

Please sign in to comment.