Support all google classroom course work types.
Previously, only the assignment type course works are needed from school tools. Now all the course work types need to be supported. Bug: 396203403 Change-Id: I8594e52a253fc2e94a37ddb99fa85841e013418c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6261749 Reviewed-by: Benjamin Zielinski <bzielinski@google.com> Commit-Queue: Zifan Zhang <zifanzhang@google.com> Reviewed-by: Artsiom Mitrokhin <amitrokhin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1420594}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
8834879be2
commit
036c0beb7a
ash/webui/boca_ui
mojom
provider
resources
chrome/test/data/webui/chromeos/boca_ui
google_apis/classroom
@ -61,6 +61,14 @@ struct Material {
|
||||
MaterialType type;
|
||||
};
|
||||
|
||||
// The assignment type.
|
||||
enum AssignmentType {
|
||||
kUnspecified,
|
||||
kAssignment,
|
||||
kShortAnswerQuestion,
|
||||
kMultipleChoiceQuestion,
|
||||
};
|
||||
|
||||
// Represents a course assignment.
|
||||
struct Assignment {
|
||||
string title;
|
||||
@ -69,6 +77,7 @@ struct Assignment {
|
||||
mojo_base.mojom.JSTime last_update_time;
|
||||
// Assignment materials.
|
||||
array<Material> materials;
|
||||
AssignmentType type;
|
||||
};
|
||||
|
||||
// Represents a browser window.
|
||||
|
@ -191,8 +191,8 @@ void ClassroomPageHandlerImpl::OnListAssignmentsFetched(
|
||||
}
|
||||
|
||||
for (const auto& item : result.value()->items()) {
|
||||
if (item->type() !=
|
||||
google_apis::classroom::CourseWorkItem::Type::kAssignment) {
|
||||
if (item->type() ==
|
||||
google_apis::classroom::CourseWorkItem::Type::kUnspecified) {
|
||||
continue;
|
||||
}
|
||||
std::vector<mojom::MaterialPtr> materials = {};
|
||||
@ -200,19 +200,19 @@ void ClassroomPageHandlerImpl::OnListAssignmentsFetched(
|
||||
mojom::MaterialPtr material = mojom::Material::New();
|
||||
material->title = apiMaterial->title();
|
||||
switch (apiMaterial->type()) {
|
||||
case (google_apis::classroom::Material::Type::kSharedDriveFile):
|
||||
case google_apis::classroom::Material::Type::kSharedDriveFile:
|
||||
material->type = mojom::MaterialType::kSharedDriveFile;
|
||||
break;
|
||||
case (google_apis::classroom::Material::Type::kYoutubeVideo):
|
||||
case google_apis::classroom::Material::Type::kYoutubeVideo:
|
||||
material->type = mojom::MaterialType::kYoutubeVideo;
|
||||
break;
|
||||
case (google_apis::classroom::Material::Type::kLink):
|
||||
case google_apis::classroom::Material::Type::kLink:
|
||||
material->type = mojom::MaterialType::kLink;
|
||||
break;
|
||||
case (google_apis::classroom::Material::Type::kForm):
|
||||
case google_apis::classroom::Material::Type::kForm:
|
||||
material->type = mojom::MaterialType::kForm;
|
||||
break;
|
||||
case (google_apis::classroom::Material::Type::kUnknown):
|
||||
case google_apis::classroom::Material::Type::kUnknown:
|
||||
default:
|
||||
material->type = mojom::MaterialType::kUnknown;
|
||||
break;
|
||||
@ -226,6 +226,21 @@ void ClassroomPageHandlerImpl::OnListAssignmentsFetched(
|
||||
assignment->url = item->alternate_link();
|
||||
assignment->materials = std::move(materials);
|
||||
assignment->last_update_time = std::move(item->last_update());
|
||||
switch (item->type()) {
|
||||
case google_apis::classroom::CourseWorkItem::Type::kAssignment:
|
||||
assignment->type = mojom::AssignmentType::kAssignment;
|
||||
break;
|
||||
case google_apis::classroom::CourseWorkItem::Type::kShortAnswerQuestion:
|
||||
assignment->type = mojom::AssignmentType::kShortAnswerQuestion;
|
||||
break;
|
||||
case google_apis::classroom::CourseWorkItem::Type::
|
||||
kMultipleChoiceQuestion:
|
||||
assignment->type = mojom::AssignmentType::kMultipleChoiceQuestion;
|
||||
break;
|
||||
case google_apis::classroom::CourseWorkItem::Type::kUnspecified:
|
||||
default:
|
||||
assignment->type = mojom::AssignmentType::kUnspecified;
|
||||
}
|
||||
|
||||
fetched_assignments->push_back(std::move(assignment));
|
||||
}
|
||||
|
@ -609,11 +609,31 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "question-id",
|
||||
"title": "question-title",
|
||||
"alternateLink": "http://question-url.com",
|
||||
"id": "short-answer-question-id",
|
||||
"title": "short-answer-question-title",
|
||||
"alternateLink": "http://short-answer-question-url.com",
|
||||
"workType": "SHORT_ANSWER_QUESTION",
|
||||
"updateTime": "2025-04-05T04:05:06.700Z"
|
||||
},
|
||||
{
|
||||
"id": "multiple-choice-question-id",
|
||||
"title": "multiple-choice-question-title",
|
||||
"alternateLink": "http://multiple-choice-question-url.com",
|
||||
"workType": "MULTIPLE_CHOICE_QUESTION",
|
||||
"updateTime": "2025-04-05T04:05:06.700Z"
|
||||
},
|
||||
{
|
||||
"id": "type-unspecified-id",
|
||||
"title": "type-unspecified-title",
|
||||
"alternateLink": "http://type-unspecified-url.com",
|
||||
"workType": "COURSE_WORK_TYPE_UNSPECIFIED",
|
||||
"updateTime": "2025-04-05T04:05:06.700Z"
|
||||
},
|
||||
{
|
||||
"id": "no-type-id",
|
||||
"title": "no-type-title",
|
||||
"alternateLink": "http://no-type-url.com",
|
||||
"updateTime": "2025-04-05T04:05:06.700Z"
|
||||
}
|
||||
]
|
||||
})"))));
|
||||
@ -633,10 +653,11 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
google_apis::test_util::CreateQuitCallback(&run_loop, callback.Get()));
|
||||
run_loop.Run();
|
||||
|
||||
ASSERT_EQ(response.size(), 4u);
|
||||
ASSERT_EQ(response.size(), 6u);
|
||||
EXPECT_EQ(response.at(0)->title, "assignment-multiple-materials-title");
|
||||
EXPECT_EQ(response.at(0)->url,
|
||||
GURL("http://assignment-multiple-materials-url.com"));
|
||||
EXPECT_EQ(response.at(0)->type, mojom::AssignmentType::kAssignment);
|
||||
EXPECT_EQ(
|
||||
google_apis::util::FormatTimeAsString(response.at(0)->last_update_time),
|
||||
"2025-01-01T00:00:00.000Z");
|
||||
@ -651,6 +672,7 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
EXPECT_EQ(response.at(1)->title, "assignment-link-materials-title");
|
||||
EXPECT_EQ(response.at(1)->url,
|
||||
GURL("http://assignment-link-materials-url.com"));
|
||||
EXPECT_EQ(response.at(1)->type, mojom::AssignmentType::kAssignment);
|
||||
EXPECT_EQ(
|
||||
google_apis::util::FormatTimeAsString(response.at(1)->last_update_time),
|
||||
"2025-01-02T01:02:03.400Z");
|
||||
@ -662,6 +684,7 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
EXPECT_EQ(response.at(2)->title, "assignment-form-materials-title");
|
||||
EXPECT_EQ(response.at(2)->url,
|
||||
GURL("http://assignment-form-materials-url.com"));
|
||||
EXPECT_EQ(response.at(2)->type, mojom::AssignmentType::kAssignment);
|
||||
EXPECT_EQ(
|
||||
google_apis::util::FormatTimeAsString(response.at(2)->last_update_time),
|
||||
"2025-02-03T02:03:04.500Z");
|
||||
@ -670,6 +693,7 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
EXPECT_EQ(response.at(2)->materials.at(0)->type, mojom::MaterialType::kForm);
|
||||
|
||||
EXPECT_EQ(response.at(3)->title, "assignment-unknown-materials-title");
|
||||
EXPECT_EQ(response.at(3)->type, mojom::AssignmentType::kAssignment);
|
||||
EXPECT_EQ(response.at(3)->url,
|
||||
GURL("http://assignment-unknown-materials-url.com"));
|
||||
EXPECT_EQ(
|
||||
@ -678,6 +702,22 @@ TEST_F(ClassroomPageHandlerImplTest, ListAllAssignments) {
|
||||
EXPECT_EQ(response.at(3)->materials.size(), 1u);
|
||||
EXPECT_EQ(response.at(3)->materials.at(0)->type,
|
||||
mojom::MaterialType::kUnknown);
|
||||
|
||||
EXPECT_EQ(response.at(4)->title, "short-answer-question-title");
|
||||
EXPECT_EQ(response.at(4)->url, GURL("http://short-answer-question-url.com"));
|
||||
EXPECT_EQ(response.at(4)->type, mojom::AssignmentType::kShortAnswerQuestion);
|
||||
EXPECT_EQ(
|
||||
google_apis::util::FormatTimeAsString(response.at(3)->last_update_time),
|
||||
"2025-03-04T03:04:05.600Z");
|
||||
|
||||
EXPECT_EQ(response.at(5)->title, "multiple-choice-question-title");
|
||||
EXPECT_EQ(response.at(5)->url,
|
||||
GURL("http://multiple-choice-question-url.com"));
|
||||
EXPECT_EQ(response.at(5)->type,
|
||||
mojom::AssignmentType::kMultipleChoiceQuestion);
|
||||
EXPECT_EQ(
|
||||
google_apis::util::FormatTimeAsString(response.at(3)->last_update_time),
|
||||
"2025-03-04T03:04:05.600Z");
|
||||
}
|
||||
|
||||
TEST_F(ClassroomPageHandlerImplTest, ListAssignmentsOnHttpError) {
|
||||
|
@ -52,6 +52,7 @@ export declare interface Assignment {
|
||||
url: string;
|
||||
lastUpdateTime: Date;
|
||||
materials: Material[];
|
||||
type: AssignmentType;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,6 +143,16 @@ export enum MaterialType {
|
||||
FORM = 4,
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare course assignment type enum type
|
||||
*/
|
||||
export enum AssignmentType {
|
||||
UNSPECIFIED = 0,
|
||||
ASSIGNMENT = 1,
|
||||
SHORT_ANSWER_QUESTION = 2,
|
||||
MULTIPLE_CHOICE_QUESTION = 3,
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare controlled tab
|
||||
*/
|
||||
|
@ -155,6 +155,7 @@ export class ClientDelegateFactory {
|
||||
materials: assignment.materials.map((material: MaterialMojom) => {
|
||||
return {title: material.title, type: material.type.valueOf()};
|
||||
}),
|
||||
type: assignment.type.valueOf(),
|
||||
};
|
||||
});
|
||||
},
|
||||
|
@ -64,6 +64,7 @@ class MockRemoteHandler extends PageHandlerRemote {
|
||||
{title: 'material-title-1', type: 0},
|
||||
{title: 'material-title-2', type: 1},
|
||||
],
|
||||
type: 0,
|
||||
},
|
||||
{
|
||||
title: 'assignment-title2',
|
||||
@ -73,6 +74,7 @@ class MockRemoteHandler extends PageHandlerRemote {
|
||||
{title: 'material-title-3', type: 2},
|
||||
{title: 'material-title-4', type: 3},
|
||||
],
|
||||
type: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
@ -375,6 +377,7 @@ suite('ClientDelegateTest', function() {
|
||||
{title: 'material-title-1', type: 0},
|
||||
{title: 'material-title-2', type: 1},
|
||||
],
|
||||
type: 0,
|
||||
},
|
||||
{
|
||||
title: 'assignment-title2',
|
||||
@ -384,6 +387,7 @@ suite('ClientDelegateTest', function() {
|
||||
{title: 'material-title-3', type: 2},
|
||||
{title: 'material-title-4', type: 3},
|
||||
],
|
||||
type: 1,
|
||||
},
|
||||
],
|
||||
result);
|
||||
|
@ -47,6 +47,10 @@ constexpr char kApiResponseCourseWorkItemMaterialFormKey[] = "form";
|
||||
|
||||
constexpr char kPublishedCourseWorkItemState[] = "PUBLISHED";
|
||||
constexpr char kAssignmentCourseWorkItemType[] = "ASSIGNMENT";
|
||||
constexpr char kShortAnswerQuestionCourseWorkItemType[] =
|
||||
"SHORT_ANSWER_QUESTION";
|
||||
constexpr char kMultipleChoiceQuestionCourseWorkItemType[] =
|
||||
"MULTIPLE_CHOICE_QUESTION";
|
||||
|
||||
bool ConvertCourseWorkItemState(std::string_view input,
|
||||
CourseWorkItem::State* output) {
|
||||
@ -58,9 +62,15 @@ bool ConvertCourseWorkItemState(std::string_view input,
|
||||
|
||||
bool ConvertCourseWorkItemType(std::string_view input,
|
||||
CourseWorkItem::Type* output) {
|
||||
*output = input == kAssignmentCourseWorkItemType
|
||||
? CourseWorkItem::Type::kAssignment
|
||||
: CourseWorkItem::Type::kOther;
|
||||
if (input == kAssignmentCourseWorkItemType) {
|
||||
*output = CourseWorkItem::Type::kAssignment;
|
||||
} else if (input == kShortAnswerQuestionCourseWorkItemType) {
|
||||
*output = CourseWorkItem::Type::kShortAnswerQuestion;
|
||||
} else if (input == kMultipleChoiceQuestionCourseWorkItemType) {
|
||||
*output = CourseWorkItem::Type::kMultipleChoiceQuestion;
|
||||
} else {
|
||||
*output = CourseWorkItem::Type::kUnspecified;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -60,11 +60,11 @@ class CourseWorkItem {
|
||||
};
|
||||
|
||||
// Course work item type.
|
||||
// There are more types can be returned by the API, but current users only
|
||||
// need "ASSIGNMENT" course work type.
|
||||
enum class Type {
|
||||
kAssignment,
|
||||
kOther,
|
||||
kShortAnswerQuestion,
|
||||
kMultipleChoiceQuestion,
|
||||
kUnspecified,
|
||||
};
|
||||
|
||||
// Joined due date and due time of the course work item.
|
||||
@ -124,7 +124,7 @@ class CourseWorkItem {
|
||||
State state_ = State::kOther;
|
||||
|
||||
// Type of this course work item.
|
||||
Type type_ = Type::kOther;
|
||||
Type type_ = Type::kUnspecified;
|
||||
|
||||
// Absolute link to this course work in the Classroom web UI.
|
||||
GURL alternate_link_;
|
||||
|
@ -46,12 +46,38 @@ TEST(ClassroomApiCourseWorkResponseTypesTest, ConvertsCourseWork) {
|
||||
},
|
||||
{
|
||||
"id": "course-work-item-2",
|
||||
"title": "Math multiple choice question",
|
||||
"title": "Math short answer question",
|
||||
"state": "DRAFT",
|
||||
"alternateLink": "https://classroom.google.com/c/ghi/a/jkl/details",
|
||||
"creationTime": "2023-04-03T00:10:55.000Z",
|
||||
"updateTime": "2023-04-04T00:10:55.000Z",
|
||||
"workType": "SHORT_ANSWER_QUESTION"
|
||||
},
|
||||
{
|
||||
"id": "course-work-item-3",
|
||||
"title": "Math multiple choice question",
|
||||
"state": "DRAFT",
|
||||
"alternateLink": "https://classroom.google.com/c/ghi/a/jkl/details",
|
||||
"creationTime": "2023-04-03T00:10:55.000Z",
|
||||
"updateTime": "2023-04-04T00:10:55.000Z",
|
||||
"workType": "MULTIPLE_CHOICE_QUESTION"
|
||||
},
|
||||
{
|
||||
"id": "course-work-item-4",
|
||||
"title": "Math type unspecified",
|
||||
"state": "DRAFT",
|
||||
"alternateLink": "https://classroom.google.com/c/ghi/a/jkl/details",
|
||||
"creationTime": "2023-04-03T00:10:55.000Z",
|
||||
"updateTime": "2023-04-04T00:10:55.000Z",
|
||||
"workType": "COURSE_WORK_TYPE_UNSPECIFIED"
|
||||
},
|
||||
{
|
||||
"id": "course-work-item-5",
|
||||
"title": "Math no work type",
|
||||
"state": "DRAFT",
|
||||
"alternateLink": "https://classroom.google.com/c/ghi/a/jkl/details",
|
||||
"creationTime": "2023-04-03T00:10:55.000Z",
|
||||
"updateTime": "2023-04-04T00:10:55.000Z"
|
||||
}
|
||||
]
|
||||
})");
|
||||
@ -59,7 +85,7 @@ TEST(ClassroomApiCourseWorkResponseTypesTest, ConvertsCourseWork) {
|
||||
|
||||
const auto course_work = CourseWork::CreateFrom(raw_course_work.value());
|
||||
ASSERT_TRUE(course_work);
|
||||
EXPECT_EQ(course_work->items().size(), 2u);
|
||||
EXPECT_EQ(course_work->items().size(), 5u);
|
||||
EXPECT_TRUE(course_work->next_page_token().empty());
|
||||
|
||||
EXPECT_EQ(course_work->items().at(0)->id(), "course-work-item-1");
|
||||
@ -79,8 +105,7 @@ TEST(ClassroomApiCourseWorkResponseTypesTest, ConvertsCourseWork) {
|
||||
CourseWorkItem::Type::kAssignment);
|
||||
|
||||
EXPECT_EQ(course_work->items().at(1)->id(), "course-work-item-2");
|
||||
EXPECT_EQ(course_work->items().at(1)->title(),
|
||||
"Math multiple choice question");
|
||||
EXPECT_EQ(course_work->items().at(1)->title(), "Math short answer question");
|
||||
EXPECT_EQ(course_work->items().at(1)->state(), CourseWorkItem::State::kOther);
|
||||
EXPECT_EQ(course_work->items().at(1)->alternate_link(),
|
||||
"https://classroom.google.com/c/ghi/a/jkl/details");
|
||||
@ -91,7 +116,54 @@ TEST(ClassroomApiCourseWorkResponseTypesTest, ConvertsCourseWork) {
|
||||
"2023-04-03T00:10:55.000Z");
|
||||
EXPECT_EQ(util::FormatTimeAsString(course_work->items().at(1)->last_update()),
|
||||
"2023-04-04T00:10:55.000Z");
|
||||
EXPECT_EQ(course_work->items().at(1)->type(), CourseWorkItem::Type::kOther);
|
||||
EXPECT_EQ(course_work->items().at(1)->type(),
|
||||
CourseWorkItem::Type::kShortAnswerQuestion);
|
||||
|
||||
EXPECT_EQ(course_work->items().at(2)->id(), "course-work-item-3");
|
||||
EXPECT_EQ(course_work->items().at(2)->title(),
|
||||
"Math multiple choice question");
|
||||
EXPECT_EQ(course_work->items().at(2)->state(), CourseWorkItem::State::kOther);
|
||||
EXPECT_EQ(course_work->items().at(2)->alternate_link(),
|
||||
"https://classroom.google.com/c/ghi/a/jkl/details");
|
||||
EXPECT_FALSE(course_work->items().at(2)->due_date_time());
|
||||
EXPECT_FALSE(course_work->items().at(2)->due_date_time());
|
||||
EXPECT_EQ(
|
||||
util::FormatTimeAsString(course_work->items().at(2)->creation_time()),
|
||||
"2023-04-03T00:10:55.000Z");
|
||||
EXPECT_EQ(util::FormatTimeAsString(course_work->items().at(2)->last_update()),
|
||||
"2023-04-04T00:10:55.000Z");
|
||||
EXPECT_EQ(course_work->items().at(2)->type(),
|
||||
CourseWorkItem::Type::kMultipleChoiceQuestion);
|
||||
|
||||
EXPECT_EQ(course_work->items().at(3)->id(), "course-work-item-4");
|
||||
EXPECT_EQ(course_work->items().at(3)->title(), "Math type unspecified");
|
||||
EXPECT_EQ(course_work->items().at(3)->state(), CourseWorkItem::State::kOther);
|
||||
EXPECT_EQ(course_work->items().at(3)->alternate_link(),
|
||||
"https://classroom.google.com/c/ghi/a/jkl/details");
|
||||
EXPECT_FALSE(course_work->items().at(3)->due_date_time());
|
||||
EXPECT_FALSE(course_work->items().at(3)->due_date_time());
|
||||
EXPECT_EQ(
|
||||
util::FormatTimeAsString(course_work->items().at(3)->creation_time()),
|
||||
"2023-04-03T00:10:55.000Z");
|
||||
EXPECT_EQ(util::FormatTimeAsString(course_work->items().at(3)->last_update()),
|
||||
"2023-04-04T00:10:55.000Z");
|
||||
EXPECT_EQ(course_work->items().at(3)->type(),
|
||||
CourseWorkItem::Type::kUnspecified);
|
||||
|
||||
EXPECT_EQ(course_work->items().at(4)->id(), "course-work-item-5");
|
||||
EXPECT_EQ(course_work->items().at(4)->title(), "Math no work type");
|
||||
EXPECT_EQ(course_work->items().at(4)->state(), CourseWorkItem::State::kOther);
|
||||
EXPECT_EQ(course_work->items().at(4)->alternate_link(),
|
||||
"https://classroom.google.com/c/ghi/a/jkl/details");
|
||||
EXPECT_FALSE(course_work->items().at(4)->due_date_time());
|
||||
EXPECT_FALSE(course_work->items().at(4)->due_date_time());
|
||||
EXPECT_EQ(
|
||||
util::FormatTimeAsString(course_work->items().at(4)->creation_time()),
|
||||
"2023-04-03T00:10:55.000Z");
|
||||
EXPECT_EQ(util::FormatTimeAsString(course_work->items().at(4)->last_update()),
|
||||
"2023-04-04T00:10:55.000Z");
|
||||
EXPECT_EQ(course_work->items().at(4)->type(),
|
||||
CourseWorkItem::Type::kUnspecified);
|
||||
}
|
||||
|
||||
TEST(ClassroomApiCourseWorkResponseTypesTest, ConvertsNextPageToken) {
|
||||
|
Reference in New Issue
Block a user